我遇到一些问题,以任何文件名转义方括号。
我需要比较两个列表。 ls输出是第一个列表,第二个是ARQ02。
#!/bin/bash exec 3< <(ls /home/lint) while read arq <&3; do var=`grep -e "$arq" ARQ02` if [ "$?" -ne 0 ] ; then echo "$arq" >> result fi done exec 3<&-
对不起,我的英语不好。
你直接的问题是,你必须指示grep
将搜索项解释为文字而不是正则表达式,使用-F
选项 :
var=$(grep -Fe "$arq" ARQ02)
这样一来,任何碰巧存在于ls /home/lint
输出中的正则表达式元字符(如[
和]
)仍将被视为字面值 ,并不会中断grep
调用。
也就是说,它看起来像你的命令可以简化 ,例如通过使用 -f
选项 , 直接使用ls /home/lint
的输出作为一次搜索字符串传递给grep
的集合 :
grep -Ff <(ls /home/lint) ARQ02 > result
<(...)
是一个所谓的进程替换 ,简单地说,它将来自命令的输出显示为(临时) 文件 ,这就是-f
期望的:包含grep
的搜索项的文件。
或者,如果:
ARQ02
的行ARQ02
包含与ls /home/lint
的输出中的文件名完全匹配的一些文件名,
你不介意排序或想排序result
中存储的匹配,
考虑HuStmpHrrr的有用答案 。
我必须假设我的解释是正确的。 基于此,我可以提出一个oneliner轻松解决你的解决方案。 有2个假设我需要在这里:你的文件名不包含回车,你正在使用现代bash:
comm -23 <(printf "%s\n" * | sort) <(sort ARQ02)
在bash中<()
发出一个子shell,并将stdout作为一个文件传递。 comm
是计算2个输入流差的命令。
详细解释,
comm -23 # suppress files unique in ARQ02 and files in common <(printf "%s\n" * | # print all the files in local folder with new line breaker sort) # sort them <(sort ARQ02)
这是必要的排序为comm
只增量比较。