将命令输出存储在数组中并一一打印

将命令输出存储在数组中并一一打印

这是我的命令:

cat httpd.conf | grep ^LogFormat | awk -F\" '{print $(NF)}'

输出:

commonsess
common

或者可以是任意数量的值,我需要将这些值存储在一个数组中并一一打印......使用它们的索引号。

答案1

在 shell 中使用数组或循环通常是不良编码实践的迹象。 shell 是运行其他命令的工具。awk是使用文本记录中的字段执行复杂任务的典型命令。您希望awk为您的任务调用一次,而不是要运行数百个命令的循环。

如果您想打印以 开头的行的索引和最后一个字段名称^LogFormat,则为:

awk '/^LogFormat/{print n++, $NF}' httpd.conf

不需要cat(用于连接),也不需要grepawk是 的超集grep)或 shell 数组或 shell 循环。

答案2

从策略上来说,使用cat, grep and awk通常是错误的。你现在有

cat /etc/httpd/conf/httpd.conf | grep ^LogLevel | awk -F\" '{print $(NF)}'

要读取数组中的行,您可以使用read

while read -rd '' -a array
 do array+=("$REPLY")
 done < <(awk -F\" '/^LogFormat/{ print $(NF)}' httpd.conf)
printf '%s\n' "${array[0]}"

答案3

简而言之
您可以使用:

a=( $(awk '/^LogFormat/{print $(NF)}' httpd.conf) )

将 httpd.conf 中的单词放入数组变量中a

您现在可以通过索引访问元素:

$ echo ${a[2]}
common

解释和说明

阿辛宁数组:

$ a=( e1 e2 e3 )
$ echo "count: ${#a}, a[2]: \"${a[2]}\""  
count: 3, a[2]: "e2"

一些贝壳设置:

对于这个例子来说,这不是必需的,因为我们知道我们只有单词作为值,但总的来说,这是非常重要的。如果值包含or ,
我们需要一个选项来防止通配。 另外,如果不是简单的话,我们应该根据我们的数据设置内部字段分隔符IFS(并保存和恢复它)。-f*?

$ # set -f
$ # IFS=$'\n'

我们的测试输入:

$ in=httpd.conf
$ grep '^LogFormat' "$in"  | awk -F\" '{print $(NF)}'
 combined
 common
 referer
 agent

和你的原来的命令:

$ a=( $(cat "$in" | grep '^LogFormat' | awk -F\" '{print $(NF)}') )
$ echo "count: ${#a}, a[2]: \"${a[2]}\""
count: 4, a[2]: " common"

随着更短@StéphaneChazelas 的版本:

$ a=( $(awk '/^LogFormat/{print $(NF)}' $in) )
$ echo "count: ${#a}, a[2]: \"${a[2]}\""  
count: 4, a[2]: "common"

相关内容