这是我的命令:
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
(用于连接),也不需要grep
(awk
是 的超集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"