将 grep 的匹配项保存为数组

将 grep 的匹配项保存为数组

我有一个包含以下内容的文件:

FILETYPE=A:B:C:D

如何在 Linux 上的 ksh 脚本中grep取出ABCD它们保存为数组?我试过

FILETYPES=`grep "FILETYPE" ${CONF_FILE} | awk -F: '{print $NF}'`

但这只能得到最后一个。

答案1

在 GNU/Linux 上,使用 ksh93 或 mksh(或zsh的 ksh 仿真模式),您可以执行以下操作:

set -o noglob
filetypes=( $(grep -Po 'FILETYPE=\K.*' < "$CONF_FILE" | tr ':' ' ') )

(假设 的默认值$IFS

或者,更惯用的说法是:

set -o noglob
IFS=:
filetypes=( $(grep -Po 'FILETYPE=\K.*' < "$CONF_FILE"))

请注意,我使用小写字母作为数组名称,这通常更安全,因为环境变量通常大写。将命令的输出保存为数组的方法是:

array=( $(command) )

禁用 glob 并设置字段分隔符后。

然后,命令本身grep(这里假设 GNUgrep或与 Perl 兼容的正则表达式支持启用(-P)),这些给了我们\K这意味着“丢弃迄今为止匹配的任何内容”。导致仅打印该行的匹配部分,并与 结合使用,-o使其仅打印在此处。最后,将替换为恰好位于默认值中的空格:grep\KA:B:C:Dtr:$IFS

$ printf '%s\n' "${filetypes[0]}"
A
$ printf '%s\n' "${filetypes[3]}" 
D

答案2

简短回答:

array=( `grep -Po '(?<=FILETYPE=).*$' $CONFIG_FILE | tr ':' ' '` )

说明:grep 使用“look Behind”断言返回“FILETYPE=”后面的任何内容。

它最终会将数组声明为:

array=(A B C D)

然后测试:

echo "${array[0]} ${array[1]} ${array[2]} ${array[3]}"

印刷:

A B C D

答案3

ksh93mksh

{ read -rd=; IFS=: read -rA filetypes; } <file

上面的命令{...;}将首先读取并包括=输入中的第一个字符。这部分输入将存储在REPLY变量中,以后不会用于任何用途。然后代码从那里开始并将:- 分隔的字符串读入数组中filetypes

-din 选项使命令读取到给定字符(而不是换行符)read。该命令的ksh选项-A使其读入索引数组而不是字符串变量。使用 时-A,变量的值IFS用于分割输入中的数组元素。

测试:

$ cat file
FILETYPE=A:B:C:D
$ { read -rd=; IFS=: read -rA filetypes; } <file
$ printf '"%s"\n' "${filetypes[@]}"
"A"
"B"
"C"
"D"

更改-A-a将使代码在bash.


如果文件包含您可能不想读取的其他行,则使用ksh93, 使用

grep '^FILETYPE=' file | { read -rd=; IFS=: read -rA filetypes; }

请注意,除非设置了 shell 选项并且代码在禁用作业控制(并更改为如上所述)的情况下在非交互式 shell(即脚本)中运行,否则这在mkshNor中不起作用。bashlastpipe-A-a

相关内容