How can I retrieve the first word of the output of a command in Bash?
我有一个命令,例如:
1 | echo"word1 word2" | .... |
管道后面应该放什么?
如果您必须处理尾随空格,AWK 是一个不错的选择,因为它会为您处理好它:
1 | echo" word1 word2" | awk '{print $1;}' # Prints"word1" |
cut 不会处理这个问题:
1 | echo" word1 word2" | cut -f 1 -d"" # Prints nothing/whitespace |
\\'cut\\' 此处不打印任何内容/空格,因为空格之前的第一件事是另一个空格。
没有任何需要使用外部命令。 Bash 本身可以完成这项工作。假设 "word1 word2" 你从某个地方得到并存储在一个变量中,例如,
1 2 3 4 5 6 | $ string="word1 word2" $ set -- $string $ echo $1 word1 $ echo $2 word2 |
现在您可以根据需要将
我认为一种有效的方法是使用 Bash 数组:
1 2 | 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 |
另外,您可以直接在管道中读取数组:
1 | echo"word1 word2" | while read -a array; do echo"${array[0]}" ; done |
1 | echo"word1 word2 word3" | { read first rest ; echo $first ; } |
这样做的好处是不使用外部命令,并且保持 $1、$2 等变量不变。
使用 shell 参数扩展
这是另一种使用 shell 参数扩展的解决方案。它处理第一个单词后的多个空格。处理第一个单词前面的空格需要一个额外的扩展。
1 2 3 4 5 6 7 | string='word1 word2' echo ${string%% *} word1 string='word1 word2 ' echo ${string%% *} word1 |
解释
如果你确定没有前导空格,你可以使用 Bash 参数替换:
1 2 3 | $ string="word1 word2" $ echo ${string/%\\ */} word1 |
注意逃离单个空间。有关替换模式的更多示例,请参见此处。如果您的 Bash > 3.0,您还可以使用正则表达式匹配来处理前导空格 - 请参见此处:
1 2 3 4 | $ string=" word1 word2" $ [[ ${string} =~ \\ *([^\\ ]*) ]] $ echo ${BASH_REMATCH[1]} word1 |
你可以试试 AWK:
1 | echo"word1 word2" | awk '{ print $1 }' |
使用 AWK 可以很容易地选择您喜欢的任何单词(
我想知道几个最佳答案在速度方面是如何衡量的。我测试了以下内容:
1 @mattbh\\'s
1 | echo"..." | awk '{print $1;}' |
2 @ghostdog74\\'s
1 | string="..."; set -- $string; echo $1 |
3 @boontawee-home\\'s
1 | echo"..." | { read -a array ; echo ${array[0]} ; } |
和 4 @boontawee-home\\'s
1 | echo"..." | { read first _ ; echo $first ; } |
我在 macOS 上的 zsh 终端中的 Bash 脚本中使用 Python 的
1 2 3 4 5 6 | Method Time -------------------------------- 1. awk 9.2 ms 2. set 11.6 ms (1.26 *"1") 3. read -a 11.7 ms (1.27 *"1") 4. read 13.6 ms (1.48 *"1") |
1 | echo"word1 word2" | cut -f 1 -d"" |
cut 从由字符串 " " (
-
如果字符串在变量中:
1
2
3
4string="word1 word2"
read -r first _ <<<"$string"
printf '%s\
'"$first" -
如果您在管道中工作:第一种情况:您只需要第一行的第一个单词:
1
2
3printf '%s\
'"word1 word2""line2" | { read -r first _; printf '%s\
'"$first"; }第二种情况:你想要每行的第一个单词:
1
2
3printf '%s\
'"word1 word2""worda wordb" | while read -r first _; do printf '%s\
'"$first"; done
如果有前导空格,这些工作:
1 2 3 | printf '%s\ '" word1 word2" | { read -r first _; printf '%s\ '"$first"; } |
由于 Perl 包含了 AWK 的功能,这也可以用 Perl 来解决:
1 | echo" word1 word2" | perl -lane 'print $F[0]' |
我正在使用既没有 Perl、AWK 或 Python 的嵌入式设备,而是使用 sed 来完成。它支持在第一个单词之前有多个空格(
1 2 | VARIABLE=" first_word_with_spaces_before_and_after another_word " echo $VARIABLE | sed 's/ *\\([^ ]*\\).*/\\1/' |
这在 grepping