Jim*_*son 25 bash command-line
以下是一个简单的Bash命令行:
grep -li 'regex' "filename with spaces" "filename"
Run Code Online (Sandbox Code Playgroud)
没问题.以下工作也很好:
grep -li 'regex' $(<listOfFiles.txt)
Run Code Online (Sandbox Code Playgroud)
其中listOfFiles.txt包含要grepped的文件名列表,每行一个文件名.
listOfFiles.txt包含带有嵌入空格的文件名时会出现此问题.在我试过(见下文),所有的情况下,击分裂的空间,以便文件名,例如,在一行listOfFiles.txt
包含类似名称./this is a file.xml最终设法在每一片上运行的grep( ,,./this 和).isafile.xml
我以为我是一个相对先进的Bash用户,但我找不到一个简单的魔术咒语来让这个工作.这是我尝试过的东西.
grep -li 'regex' `cat listOfFiles.txt`
Run Code Online (Sandbox Code Playgroud)
如上所述失败(我真的没想到这会起作用),所以我想我会在每个文件名周围加上引号:
grep -li 'regex' `sed -e 's/.*/"&"/' listOfFiles.txt`
Run Code Online (Sandbox Code Playgroud)
Bash将引号解释为文件名的一部分,并为每个文件提供"No such file or directory"(并且仍然使用空格分割文件名)
for i in $(<listOfFiles.txt); do grep -li 'regex' "$i"; done
Run Code Online (Sandbox Code Playgroud)
这未按原始的尝试(也就是说,它的行为就好像引号被忽略),是非常缓慢的,因为它必须每个文件启动一个"grep"可以替代过程在处理一个调用的所有文件.
以下工作,但如果正则表达式包含shell元字符,则需要一些小心的双重转义:
eval grep -li 'regex' `sed -e 's/.*/"&"/' listOfFiles.txt`
Run Code Online (Sandbox Code Playgroud)
这是构造命令行的唯一方法,以便正确处理带空格的文件名吗?
Ste*_*202 44
试试这个:
(IFS=$'\n'; grep -li 'regex' $(<listOfFiles.txt))
Run Code Online (Sandbox Code Playgroud)
IFS是内部字段分隔符.设置它以$'\n'告诉Bash使用换行符来分隔文件名.它的默认值是$' \t\n',可以使用打印cat -etv <<<"$IFS".
将括号括在括号中会启动子shell,以便只有括号内的命令才会受到自定义IFS值的影响.
cat listOfFiles.txt |tr '\n' '\0' |xargs -0 grep -li 'regex'
Run Code Online (Sandbox Code Playgroud)
xargs上的-0选项告诉xargs使用空字符而不是空格作为文件名终止符.tr命令将传入的换行符转换为空字符.
这符合OP的要求,即grep不能多次调用.根据我的经验,大量文件避免了grep的多次调用,大大提高了性能.
此方案还避免了OP原始方法中的错误,因为他的方案将破坏listOfFiles.txt包含多个文件的位置,这些文件将超过命令的缓冲区大小.xargs知道最大命令大小,并将多次调用grep以避免该问题.
使用xargs和grep的一个相关问题是,当使用多个文件调用时,grep将使用文件名为输出添加前缀.因为xargs使用多个文件调用grep,所以将接收带有前缀的文件名的输出,但不是listOfFiles.txt中的一个文件的情况,或者是最后一次调用包含一个文件名的多个调用的情况.要实现一致的输出,请将/ dev/null添加到grep命令:
cat listOfFiles.txt |tr '\n' '\0' |xargs -0 grep -i 'regex' /dev/null
Run Code Online (Sandbox Code Playgroud)
请注意,这不是OP的问题,因为他在grep上使用-l选项; 然而,这可能是其他人的问题.
这有效:
while read file; do grep -li dtw "$file"; done < listOfFiles.txt
Run Code Online (Sandbox Code Playgroud)