这是继续将数组存储为非交互式 shell 的环境变量 - 智库101 - 一个基于CC版权的问答分享平台。善行难陀,让我问另一个问题。
我想找到包含特定正则表达式匹配的所有 Markdown 文件,然后按升序对文件(包含最多搜索词)的输出进行排序。
GREP(){
export Regex
xargs -0 -I "{}" bash -c 'grep "${GrepOption[@]}" --only-matching --with-filename --extended-regexp --regexp="${Regex}" "${1}" 2> /dev/null | wc -l | xargs printf "${1}:%s\n" ' _ "{}" \;
}
find . -name "*.md" -print0 | GREP | grep -v ':0$' | sort -n -r -k2 -t:
用户输入“${Regex}”。这里 GrepOptions 是取决于用户输入的选项数组。例如,GrepOptions 可以是GrepOptions=("--ignore-case")
grep 选项的一些其他数组。
但我无法让该数组GrepOptions
在子 shell 环境中可用。
有什么建议么?
答案1
问题是您想GrepOptions
在代码中使用数组作为环境变量。你不能这样做,因为数组无法导出。
相反,您必须将选项bash -c
以及要运行的路径名传递到脚本中grep
。
下面,我更进一步,还传递了正则表达式和多个找到的路径名,并且我是从-exec
infind
而不是使用xargs
.
我--
在脚本的调用中使用bash -c
来分隔路径名中的用户选项。
find . -name '*.md' -type f -exec bash -c '
re=$1; shift
while [[ $1 != "--" ]]; do
opts+=( "$1" )
shift
done; shift
for pathname do
printf "%s:" "$pathname"
grep -o -E -e "$re" "${opts[@]}" -- "$pathname" |
wc -l | tr -d "[:blank:]"
done | grep -v ":0$"' bash "$user_regex" "${user_options[@]}" -- {} + |
sort -t : -k2,2n
.md
这将查找当前目录或以下目录中所有文件名后缀为 的常规文件。对于成批的此类文件,bash
将执行一个脚本,该脚本采用用户提供的扩展正则表达式 ( $user_regex
)、一些用户提供的命令选项grep
($user_options
,一个数组)以及一批路径名。
内联脚本挑选正则表达式和用户选项,然后继续循环找到的文件,grep
在每个文件上运行并计算返回的行数。
每个文件的路径名都会在末尾的一个字符之后输出该数字:
。
表明没有匹配项的输出被淘汰,并对总体结果进行排序。
由于此代码处理路径名的方式,它不支持包含换行符或冒号的路径名。该user_options
数组也不能包含单独的双破折号。
答案2
bash -c 'grep ${grepOptions+$grepOptions} ....'
- grepOptions 是一个 shell 变量,包含 grep 的选项,空格分隔。
- 赤裸裸地使用 ${var+alternative} ;如果选项非空,则使用它们,否则使用 e 空的不带引号的,这会在解析中溶解
- 这意味着 shell 变量是可导出的。