我有一个包含以下内容的文件:
FILETYPE=A:B:C:D
如何在 Linux 上的 ksh 脚本中grep
取出A
、B
和C
将D
它们保存为数组?我试过
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
\K
A:B:C:D
tr
:
$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
与ksh93
或mksh
:
{ read -rd=; IFS=: read -rA filetypes; } <file
上面的命令{...;}
将首先读取并包括=
输入中的第一个字符。这部分输入将存储在REPLY
变量中,以后不会用于任何用途。然后代码从那里开始并将:
- 分隔的字符串读入数组中filetypes
。
-d
in 选项使命令读取到给定字符(而不是换行符)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(即脚本)中运行,否则这在mksh
Nor中不起作用。bash
lastpipe
-A
-a