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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2440414/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 19:03:09  来源:igfitidea点击:

How to retrieve the first word of the output of a command in bash?

bash

提问by Neuquino

I have a command, for example: echo "word1 word2". I want to put a pipe (|) and get word1 from the command.

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

echo "word1 word2" | ....

echo "word1 word2" | ....

I don't know what to put after the pipe.

我不知道在管子后面放什么。

回答by mattbh

Awk is a good option if you have to deal with trailing whitespace because it'll take care of it for you:

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

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

Cut won't take care of this though:

不过,Cut 不会处理这个:

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

'cut' here prints nothing/whitespace, because the first thing before a space was another space.

'cut' 此处不打印任何内容/空白,因为空格之前的第一件事是另一个空格。

回答by ghostdog74

no need to use external commands. Bash itself can do the job. Assuming "word1 word2" you got from somewhere and stored in a variable, eg

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

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

now you can assign $1, or $2 etc to another variable if you like.

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

回答by Isaías

I think one efficient way is the use of bash arrays:

我认为一种有效的方法是使用 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

Also, you can directly read arrays in a pipe-line:

此外,您可以直接读取管道中的数组:

echo "word1 word2" | while read -a array; do echo "${array[0]}" ; done

回答by John Marter

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

This has the advantage that is not using external commands and leaves the $1, $2, etc. variables intact.

这具有不使用外部命令并保持 $1、$2 等变量不变的优点。

回答by dsl101

If you are sure there are no leading spaces, you can use bash parameter substitution:

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

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

Watch out for escaping the single space. See herefor more examples of substitution patterns. If you have bash > 3.0, you could also use regular expression matching to cope with leading spaces - see here:

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

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

回答by mfloryan

You could try awk

你可以试试 awk

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

With awk it is really easy to pick any word you like ($1, $2, ...)

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

回答by Serge Stroobandt

Using shell parameter expansion %% *

使用 shell 参数扩展 %% *

Here is another solution using shell parameter expansion. It takes care of multiple spaces after the first word. Handling spaces in front of the first word requires one additional expansion.

这是使用shell 参数扩展的另一种解决方案。它处理第一个单词后的多个空格。处理第一个单词前面的空格需要一个额外的扩展。

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

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

Explanation

解释

The %%signifies deletingthe longest possible match of ?*(a space followed by any number of whatever other characters) in the trailingpart of string.

%%表示删除的最长可能的匹配?*(一个空格,接着任意数量的任何其他字符的)在尾部的一部分string

回答by henry

I wondered how several of the top answers measured up in terms of speed. I tested the following:

我想知道几个顶级答案在速度方面是如何衡量的。我测试了以下内容:

1@mattbh's

1@mattbh 的

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

2@ghostdog74's

2@ghostdog74

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

3@boontawee-home's

3@boontawee-home's

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

and 4@boontawee-home's

4 个@boontawee-home's

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

I measured them with Python's timeit in a Bash script in a Zsh terminal on macOS, using a test string with 215 5-letter words. Did each measurement five times (the results were all for 100 loops, best of 3), and averaged the results:

我在 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")

Nice job, voters The votes (as of this writing) match the solutions' speed!

干得好,选民投票(在撰写本文时)与解决方案的速度相匹配!

回答by lajuette

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

cut cuts the 1st field (-f 1) from a list of fields delimited by the string " " (-d " ")

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

回答by gniourf_gniourf

readis your friend:

read是你的朋友:

  • If string is in a variable:

    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"; }
    

    second case: you want the first word of each line:

    printf '%s\n' "word1 word2" "worda wordb" | while read -r first _; do printf '%s\n' "$first"; done
    
  • 如果字符串在变量中:

    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
    

These work if there are leading spaces:

如果有前导空格,这些工作:

printf '%s\n' "   word1 word2" | { read -r first _; printf '%s\n' "$first"; }