将包含'*'的egrep输出保存到bash数组

时间:2015-05-26 14:31:47

标签: arrays bash

我想将egrep输出保存到bash数组:

arr=( $(egrep -Rn 'regex') )

如果在egrep结果中碰巧是'*',则bash似乎正在将'*'扩展为当前目录中的所有文件。然后将egrep的扩展加结果保存到arr。

我该如何解决这个问题?我希望grep结果中的“*”不会改变。

1 个答案:

答案 0 :(得分:2)

使用在“正确”问题中尝试的习语可能看起来像这样:

# DON'T DO THIS.

set -f         # turn off globbing
IFS=$'\n'      # word-split only on newlines
arr=( $(...) ) # populate array
unset IFS      # return IFS to defaults (assuming it was there before)
set +f         # turn globbing back on

显然,有很多空间可以解决这个问题,并将shell置于其启动方式以外的状态(如果您的脚本具有不同的初始IFS值会怎么样?如果此代码来自需要的脚本该怎么办?要禁用的globbing才能正常工作?)。不要这样做。

与bash 3.x兼容的一种方法是使用包含换行符read -a(用于分隔字段)的IFS(读入数组)和-d(用于分隔记录)设置为NUL:

IFS=$'\n' read -r -d '' -a arr < <(egrep -Rn 'regex' && printf '\0')

添加到输入中的尾随NUL可确保read成功退出;否则,如果使用set -e,这可能会触发突然退出。

更长但更明确的方法是自己进行迭代:

arr=( )
while IFS= read -r; do
  arr+=( "$REPLY" )
done < <(egrep -Rn 'regex')

另一个,使用bash 4.x功能(readarray, AKA mapfile):

readarray -t arr < <(egrep -Rn 'regex')