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

时间:2010-03-13 23:09:17

标签: bash

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

echo "word1 word2" | ....

我不知道管道后要放什么。

11 个答案:

答案 0 :(得分:167)

如果您必须处理尾随空格,那么Awk是一个不错的选择,因为它会为您处理:

echo "   word1  word2 " | awk '{print $1;}' # Prints "word1"

Cut不会照顾这个:

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

'cut'这里不打印任何/空格,因为空格之前的第一件事是另一个空格。

答案 1 :(得分:62)

无需使用外部命令。 Bash本身可以完成这项工作。假设“word1 word2”来自某个地方并存储在变量中,例如

$ string="word1 word2"
$ set -- $string
$ echo $1
word1
$ echo $2
word2

现在,如果您愿意,可以将$ 1或$ 2等分配给另一个变量。

答案 2 :(得分:18)

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

这样做的好处是不使用外部命令,并保留$ 1,$ 2等变量。

答案 3 :(得分:13)

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

$ string="word1  word2"
$ echo ${string/%\ */}
word1

注意逃离单个空间。有关替换模式的更多示例,请参阅here。如果你有bash> 3.0,您还可以使用正则表达式匹配来处理前导空格 - 请参阅here

$ string="  word1   word2"
$ [[ ${string} =~ \ *([^\ ]*) ]]
$ echo ${BASH_REMATCH[1]}
word1

答案 4 :(得分:11)

你可以试试awk

echo "word1 word2" | awk '{ print $1 }'

使用awk可以很容易地选择你喜欢的任何单词($ 1,$ 2,...)

答案 5 :(得分:6)

使用shell参数扩展%% *

以下是使用shell parameter expansion的另一种解决方案。在第一个单词之后它会处理多个空格。处理第一个单词前面的空格需要一个额外的扩展。

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

解释

%%表示从变量*的右侧开始,删除string的最长匹配(空格后跟任意数量的其他任何字符)。< / p>

答案 6 :(得分:5)

echo "word1 word2" | cut -f 1 -d " "

剪切从由字符串“”( - d“”)分隔的字段列表中剪切第1个字段(-f 1)

答案 7 :(得分:4)

我想知道几个最佳答案如何衡量速度。我测试了以下内容:

1 @ mattbh's

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

2 @ ghostdog74的

string="..."; set -- $string; echo $1

3 @ boontawee-home's

echo "..." | { read -a array ; echo ${array[0]} ; }

4 @ boontawee-home's

echo "..." | { read first _ ; echo $first ; }

我使用带有215个5个字母单词的测试字符串,在MacOS上的Zsh终端中的Bash脚本中使用Python的timeit测量它们。每次测量五次(结果全部为100次循环,最好为3次),并对结果取平均值:

method       time
--------------------------------
1. awk       9.2ms
2. set       11.6ms (1.26 * "1")
3. read -a   11.7ms (1.27 * "1")
4. read      13.6ms (1.48 * "1")

不错的工作,选民投票(截至撰写本文时)符合解决方案的速度!

答案 8 :(得分:3)

read是你的朋友:

  • 如果字符串在变量中:

    string="word1 word2"
    read -r first _ <<< "$string"
    printf '%s\n' "$first"
    
  • 如果你正在管道中工作:第一种情况:你只需要第一行的第一个单词:

    printf '%s\n' "word1 word2" "line2" | { read -r first _; 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"; }

答案 9 :(得分:0)

由于perl结合了awk的功能,这也可以用perl解决:

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

答案 10 :(得分:0)

我正在使用一个没有perl,awk或python的嵌入式设备,而是用sed做的。它支持第一个单词之前的多个空格(cutbash解决方案无法处理)。

VARIABLE="  first_word_with_spaces_before_and_after  another_word  "
echo $VARIABLE | sed 's/ *\([^ ]*\).*/\1/'

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