我有一个命令,例如: echo "word1 word2"。我想放一个管道(|)并从命令中得到“ word1”。
echo "word1 word2"
|
echo "word1 word2" | ....
我应该在烟斗后面放什么?
echo "word1 word2" | cut -f 1 -d " "
Cut 从字符串“”(-d " ")分隔的字段列表中剪切第一个字段(-f 1)。
-d " "
-f 1
你可以试试 AWK:
echo "word1 word2" | awk '{ print $1 }'
AWK 真的很容易挑选任何你喜欢的单词($1,$2,等等)。
$1
$2
如果你不得不处理尾随的空格,AWK 是个不错的选择,因为它会帮你处理:
echo " word1 word2 " | awk '{print $1;}' # Prints "word1"
Cut 不会解决这个问题:
echo " word1 word2 " | cut -f 1 -d " " # Prints nothing/whitespace
这里的“ cut”不打印任何内容/空格,因为空格之前的第一个内容是另一个空格。
不需要使用外部命令。巴斯自己就能搞定。例如,假设“ 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,还可以使用正则表达式匹配来处理前导空格——参见 给你:
$ string=" word1 word2" $ [[ ${string} =~ \ *([^\ ]*) ]] $ echo ${BASH_REMATCH[1]} word1
read是你的朋友:
read
如果字符串在变量中:
string="word1 word2" read -r first _ <<< "$string" printf '%s\n' "$first"
If you're working in a pipe: first case: you only want the first word of the first line:
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
These work if there are leading spaces:
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
%% *
下面是使用 壳参数展开式壳参数展开式的另一种解决方案。它在第一个单词之后处理多个空格。处理第一个单词前面的空格需要一个额外的扩展。
string='word1 word2' echo ${string%% *} word1 string='word1 word2 ' echo ${string%% *} word1
%%表示 string的 跟踪部分中 删除与 *(一个空格,后跟任意数量的其他字符)匹配的时间最长的匹配。
%%
string
*
随着 Perl 整合了 AWK 的功能,这个问题也可以用 Perl 来解决:
echo " word1 word2" | perl -lane 'print $F[0]'
我使用的嵌入式设备既没有 Perl、 AWK 也没有 Python,而是使用 Sed。它在第一个单词之前支持多个空格(cut和 bash解决方案没有处理这个空格)。
cut
bash
VARIABLE=" first_word_with_spaces_before_and_after another_word " echo $VARIABLE | sed 's/ *\([^ ]*\).*/\1/'
这在将 ps用于进程 ID 时非常有用,因为这里仅使用 Bash 的其他解决方案无法删除 ps用于对齐的第一个空格。
ps
我想知道几个最好的答案是如何衡量速度的。我测试了以下几个答案:
1@mattbh’s
echo "..." | awk '{print $1;}'
2 @ghostdog74’s
string="..."; set -- $string; echo $1
3 @boontawee-home’s
echo "..." | { read -a array ; echo ${array[0]} ; }
和 4@boontawee-home 的
echo "..." | { read first _ ; echo $first ; }
我在 macOS 上的 zsh 终端使用一个带有215个5个字母单词的测试字符串,在 Bash 脚本中使用 Python 的 timeit测量它们。每个测量我都做了5次(结果都是100个循环,最好是3个循环) ,然后对结果取平均值:
timeit
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")
如果您不介意安装一个新命令,我建议您使用 选吧
在所有替代品中,它具有最简单、最直观的界面:
echo "word1 word2" | choose 0