Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Bash中检索命令输出的第一个单词?_Bash - Fatal编程技术网

如何在Bash中检索命令输出的第一个单词?

如何在Bash中检索命令输出的第一个单词?,bash,Bash,我有一个命令,例如:echo“word1-word2”。我想放置一个管道(|)并从命令中获取“word1” echo "word1 word2" | .... 我应该在管子后面放什么 echo "word1 word2" | cut -f 1 -d " " 从由字符串“(-d”“)分隔的字段列表中剪切第一个字段(-f 1)。您可以尝试AWK: echo "word1 word2" | awk '{ print $

我有一个命令,例如:
echo“word1-word2”
。我想放置一个管道(
|
)并从命令中获取“word1”

echo "word1 word2" | ....
我应该在管子后面放什么

echo "word1 word2" | cut -f 1 -d " "
从由字符串“(
-d”“
)分隔的字段列表中剪切第一个字段(
-f 1)。

您可以尝试AWK:

echo "word1 word2" | awk '{ print $1 }'
使用AWK,你可以很容易地选择任何你喜欢的单词(
$1
$2
,等等)。

如果你必须处理尾随空格,这是一个很好的选择,因为它会帮你解决:

echo "   word1  word2 " | awk '{print $1;}' # Prints "word1"
但我不会处理这个问题:

echo "  word1  word2 " | cut -f 1 -d " " # Prints nothing/whitespace

此处的“cut”不打印任何内容/空白,因为空格前的第一件事是另一个空格。

不需要使用外部命令。Bash本身可以完成这项工作。例如,假设“word1 word2”是从某处获得并存储在变量中的

$ string="word1 word2"
$ set -- $string
$ echo $1
word1
$ echo $2
word2
现在,如果愿意,您可以将
$1
$2
等分配给另一个变量

echo "word1 word2 word3" | { read first rest ; echo $first ; }

这样做的优点是不使用外部命令,并且保持$1、$2等变量不变。

如果确定没有前导空格,可以使用Bash参数替换:

$ string="word1  word2"
$ echo ${string/%\ */}
word1
小心逃离单一空间。有关替换模式的更多示例,请参见。如果Bash>3.0,还可以使用正则表达式匹配来处理前导空格-请参阅:


read
是你的朋友:

  • 如果字符串位于变量中:

    string="word1 word2"
    read -r first _ <<< "$string"
    printf '%s\n' "$first"
    
    第二种情况:您需要每行的第一个单词:

    printf '%s\n' "word1 word2" "worda wordb" | while read -r first _; do printf '%s\n' "$first"; done
    
如果存在前导空格,则这些选项有效:

printf '%s\n' "   word1 word2" | { read -r first _; printf '%s\n' "$first"; }

我认为一种有效的方法是使用Bash数组:

array=( $string ) # Do not use quotes in order to allow word expansion
echo ${array[0]}  # You can retrieve any word. Index runs from 0 to length-1
此外,还可以直接读取管线中的阵列:

echo "word1 word2" | while read -a array; do echo "${array[0]}" ; done
使用shell参数扩展
%%*
下面是另一个使用的解决方案。它处理第一个单词后的多个空格。处理第一个单词前面的空格需要一个额外的扩展

string='word1    word2'
echo ${string%% *}
word1

string='word1    word2      '
echo ${string%% *}
word1
解释
%%
表示删除
 *字符串

尾部的code>(后跟任意数量的其他字符的空格)由于Perl包含了AWK的功能,这也可以通过Perl解决:

echo " word1 word2" | perl -lane 'print $F[0]'

我使用的嵌入式设备既没有Perl、AWK也没有Python,而是使用。它支持第一个单词前面的多个空格(
cut
bash
解决方案没有处理这些空格)


这在为进程ID进行grepping
ps
时非常有用,因为此处仅使用Bash的其他解决方案无法删除
ps
用于对齐的第一个空格。

我想知道几个最重要的答案在速度方面是如何衡量的。我测试了以下内容:

@mattbh's

echo "..." | awk '{print $1;}'
@ghostdog74's

string="..."; set -- $string; echo $1
@boontawee home's

echo "..." | { read -a array ; echo ${array[0]} ; }
echo "..." | { read first _ ; echo $first ; }
和@boontawee home's

echo "..." | { read -a array ; echo ${array[0]} ; }
echo "..." | { read first _ ; echo $first ; }
我在macOS上的zsh终端上用Python的
timeit
在Bash脚本中测量了它们,使用了一个包含215个5个字母单词的测试字符串。每次测量我都做了五次(结果都是100个循环,最好是3个循环),然后取结果的平均值:

方法时间
--------------------------------
1.awk 9.2毫秒
2.设置为11.6毫秒(1.26*“1”)
3.读-11.7毫秒(1.27*“1”)
4.读13.6毫秒(1.48*“1”)


这是一种方法,但是您的cut语句不会在单词之间区分多个空格。如果他想在以后获得word2,awk解决方案是更好的解决方案。+1仅用于使用shell内置和
stdin
@Matt M.
--
表示
stdin
,因此
$string
作为
stdin
传入
stdin
是将空格分隔为参数
$1
$2
$3
,等等-就像Bash程序计算参数时一样(例如,检查
$1
$2
,等等),这种方法利用了shell自动将
stdin拆分为参数的趋势,无需使用
awk
cut
@CalebXu Not stdin,
set
设置shell参数。
word1=$(IFS=”“;set--$string;echo$1)
设置IFS以正确识别单词之间的空格。用括号括起来,以避免重击$1的原始内容。这会被破坏,因为它要进行路径名扩展。用
string=“*”
试试。惊喜。回答得好,因为这不仅对Bash有效,甚至对传统的Bourne shell也是有效的。
echo“word1 word2”{read-a array;echo${array[0]}
由于要进行路径名扩展,所以它被破坏了。用
string=“*”
试试。惊奇。使用
while
语法检索每行的第一个单词。否则,使用Boontawee Home方法。另外,请注意,
echo“${array[0]}”
已被引用,以防止gniourf-gniourf注意到的扩展。如果您尝试访问大于字数的数组索引,则不会出现错误。你只会得到一个空的line@gniourf_gniourf:如果输入受到限制,则不会中断。保持变量
$1,$2,…
不变对于脚本编写非常有用!比公认的答案要好得多,因为这也适用于任何类型的空格。是否需要分号?它应该是“前导”空格(在字符串开头),而不是“尾随”。@AlicePurcell我在没有分号的情况下尝试过它;它对我有效(MBP10.14.2)。如果字符串是例如“firstWord,secondWord”作为awk命令分隔符space@RogerOba这不是OP的问题,但您可以使用
-F“,”
用逗号覆盖默认字段分隔符(空格)。奇怪的是,您可以在破折号中测量3,因为dash不支持数组(
read-a
在dash中无效)。是的,这很奇怪。我排除了那个,做了速度测试,然后想“为什么我要把那个排除在外”,并把它加进去。移除它
echo "..." | { read first _ ; echo $first ; }