我有一个命令,例如:echo "word1 word2"
。我想放一个管道(|
)并从命令中获取word1。
echo "word1 word2" | ....
我不知道管道后要放什么。
答案 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 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做的。它支持第一个单词之前的多个空格(cut
和bash
解决方案无法处理)。
VARIABLE=" first_word_with_spaces_before_and_after another_word "
echo $VARIABLE | sed 's/ *\([^ ]*\).*/\1/'
在为进程ID点击ps
时非常有用,因为此处仅使用bash的其他解决方案无法删除ps
用于对齐的第一个空格。