![从输出中切出不同的单词](https://linux22.com/image/72900/%E4%BB%8E%E8%BE%93%E5%87%BA%E4%B8%AD%E5%88%87%E5%87%BA%E4%B8%8D%E5%90%8C%E7%9A%84%E5%8D%95%E8%AF%8D.png)
假设,在linux shell中执行命令的结果如下:
X and Y are friends
有什么方法可以对结果中的每个单词(X、and、Y、are、friends)或前 n 个单词进行切片,以便它们可以用于不同的操作?
答案1
怎么样cut
?
$ phrase="X and Y are friends"
$ cut -d " " -f 1 <<< $phrase
X
$ cut -d " " -f 2 <<< $phrase
and
$ cut -d " " -f 3 <<< $phrase
Y
$ cut -d " " -f 4 <<< $phrase
are
$ cut -d " " -f 5 <<< $phrase
friends
指定-d
分隔符(空格)和-f
字段编号(由分隔符分隔的字段)。
在上面的示例中,我已将字符串放置在变量中,但您可以从命令的输出进行管道传输:
$ mycommand | cut -d " " -f 2
and
答案2
您还可以使用以下命令直接在 shell 中进行此操作read
:
$ echo "X and Y are friends" |
while read a b c d e f
do echo "a is '$a', b is '$b', c is '$c', d is '$d', e is '$e', f is '$f'"
done
a is 'X', b is 'and', c is 'Y', d is 'are', e is 'friends', f is ''
默认分隔符是空格,但您可以通过更改变量将其设置为其他内容IFS
:
$ echo "foo:bar" | while IFS=: read a b; do echo "a is '$a', b is '$b'"; done
a is 'foo', b is 'bar'
答案3
在 shell 脚本中捕获命令的输出有两种主要方法:命令替换和read
内置。
将输出拆分为单词的简单方法是依靠 shell 内置的拆分功能,并将输出放入数组中:
words=($(echo "X and Y are friends"))
echo "The ${words[5]} are ${words[1]} and ${words[3]}"
这适用于带有数组的 shell:ksh931、mksh、bash、zsh。在其他 shell 中,除了位置参数之外,您无法存储单词列表。
set -- $(echo "X and Y are friends")
echo "The $5 are $1 and $3"
实际上,输出中的每个单词都被视为通配符模式,并由匹配文件列表(如果有)替换。 (除了在 zsh 中,除非在 sh 兼容模式下,否则只有在明确指示时才执行此操作。)例如,如果其中一个单词是*
,它将被当前目录中的文件列表替换。为了避免这种情况,请关闭通配符匹配:
set -f
words=($(echo "* and / are punctuation"))
echo "Here's some ${words[5]}: ${words[1]} and ${words[3]}"
set +f
使用read
,您可以将各个单词分配给每个变量。棘手的部分read
是,由于它从标准输入读取,因此通常用作管道中的右侧;但在大多数 shell 中(ATT ksh 和 zsh 除外),管道的两侧都在子 shell 中运行,因此变量分配会在管道外部丢失。您可以将其read
作为指令序列的一部分。
echo "X and Y are friends" | {
read -r first conjunction second verb complement remainder
echo "The $complement are $first and $second"
}
或者,在 ksh93、bash 或 zsh 中,您可以将输入传递到流程替代。
read -r first conjunction second verb complement remainder <(echo "X and Y are friends")
echo "The $complement are $first and $second"
如果你想将单词存储在数组中,你可以read -rA words
在 mksh、ksh93 和 zsh 中使用,或者read -ra words
在 bash 中使用,例如在 bash 中
read -ra words <(echo "X and Y are friends")
相当于
set -f; words=$((echo "X and Y are friends")); set +f
如果该命令输出一行,但-f
如果该选项之前已打开,则它不会重置该选项。
¹ Ksh88 有数组,但赋值使用不同的语法。
答案4
和zsh
:
upToFirst5words=(${$(my-cmd)[1,5]})
假设默认值是 IFS 的默认值,它将按序列空白(空格、制表符、换行符)或 NUL 进行拆分。
你可以做到:
argv=(${$(my-cmd)[1,5]})
对于这 5个词$1
,$2
...。$5