Answers:
如果您必须处理尾随空格,则Awk是一个不错的选择,因为它将为您处理:
echo " word1 word2 " | awk '{print $1;}' # Prints "word1"
不过,Cut不会解决此问题:
echo " word1 word2 " | cut -f 1 -d " " # Prints nothing/whitespace
这里的“剪切”不打印任何内容/空白,因为一个空间之前的第一件事就是另一个空间。
-F","
逗号来覆盖默认的字段分隔符(空格)。
无需使用外部命令。Bash本身可以胜任。假设您从某处获取“ word1 word2”,并将其存储在变量中,例如
$ string="word1 word2"
$ set -- $string
$ echo $1
word1
$ echo $2
word2
现在,您可以根据需要将$ 1或$ 2等分配给另一个变量。
stdin
。@Matt M.的--
意思是stdin
,所以$string
被传递为stdin
。stdin
是空格分隔成参数$1
,$2
,$3
等-只是当一个猛砸,程序会计算参数(如支票样$1
,$2
等等),这种方法采用shell的倾向的优势,分裂stdin
自动为参数,不再需要为awk
或cut
。
set
设置shell参数。
word1=$(IFS=" " ; set -- $string ; echo $1)
设置IFS以正确识别单词之间的空格。请用括号括起来,以免破坏$ 1的原始内容。
string="*"
。惊喜
我认为一种有效的方法是使用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
echo " word1 word2 " | { read -a array ; echo ${array[0]} ; }
string="*"
。惊喜
while
语法检索每行的每个第一个单词。否则,请使用Boontawee Home方法。另外,请注意,echo "${array[0]}"
已经引用了gniourf-gniourf,以防止扩展。
echo "word1 word2 word3" | { read first rest ; echo $first ; }
这样做的好处是不使用外部命令,而保持$ 1,$ 2等变量不变。
$1, $2, …
完整保留变量对于脚本编写来说是非常有用的功能!
%% *
这是使用shell参数扩展的另一种解决方案。它会在第一个单词之后照顾多个空格。在第一个单词前面处理空格需要进一步扩展。
string='word1 word2'
echo ${string%% *}
word1
string='word1 word2 '
echo ${string%% *}
word1
的%%
表示删除的最长可能的匹配 *
(一个空格,接着任意数量的任何其他字符的)在尾部的一部分string
。
我想知道在速度方面如何衡量几个最重要的答案。我测试了以下内容:
1 @mattbh的
echo "..." | awk '{print $1;}'
2 @ ghostdog74的
string="..."; set -- $string; echo $1
3 @ boontawee-home的
echo "..." | { read -a array ; echo ${array[0]} ; }
和4 @ boontawee-home的
echo "..." | { read first _ ; echo $first ; }
我在MacOS的Zsh终端中的Bash脚本中使用Python的timeit来测量它们,使用的测试字符串为215个5个字母的单词。进行五次测量(结果均为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")
干得好,选民👏截止本文撰稿,投票与解决方案的速度相称!
read -a
在破折号中无效)。
echo "word1 word2" | cut -f 1 -d " "
cut从由字符串““(-d”“)分隔的字段列表中切出第一个字段(-f 1)
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"; }
我使用的嵌入式设备既没有perl,awk也没有python,而是使用sed来完成的。它在第一个单词之前支持多个空格(cut
and bash
解决方案未处理)。
VARIABLE=" first_word_with_spaces_before_and_after another_word "
echo $VARIABLE | sed 's/ *\([^ ]*\).*/\1/'
这在grepping ps
进程ID 时非常有用,因为此处仅使用bash的其他解决方案无法删除ps
用于对齐的第一个空格。