Bash 查找文件夹中不包含空格的所有文件
我正试图编写一个bash脚本来查找目录中不包含空格的所有文件,但我发现了一些困难。我正在使用find和grep的组合,它似乎适用于除空格之外的所有内容。我尝试了两种方法:Bash 查找文件夹中不包含空格的所有文件,bash,grep,Bash,Grep,我正试图编写一个bash脚本来查找目录中不包含空格的所有文件,但我发现了一些困难。我正在使用find和grep的组合,它似乎适用于除空格之外的所有内容。我尝试了两种方法: find $d -name '*.js' | xargs grep -L '[ \t]*' 及 两者都不起作用。如何正确匹配空格 编辑:为了澄清,我想在文件内部进行搜索,而不是在文件名中进行搜索。您可以使用grep简单地排除结果(-v,--invert match select non-match line),其中包括查找结
find $d -name '*.js' | xargs grep -L '[ \t]*'
及
两者都不起作用。如何正确匹配空格
编辑:为了澄清,我想在文件内部进行搜索,而不是在文件名中进行搜索。您可以使用
grep
简单地排除结果(-v,--invert match select non-match line
),其中包括查找
结果中的空格……类似于:
查找无空白文件名的解决方案
find $d -name '*.js' | grep -v " "
看起来效果不错
根据您的编辑,以下解决方案应适用于您,结果仅为不包含空白内容的文件:
查找内容不包含空格的文件的解决方案(此解决方案中文件名可以包含空格)。
如果您只想返回不包含空格的文件名以及不包含空格的文件内容,我认为这两种方法的结合是可行的:
find $d -name '*.js' |grep -iRlv " " | grep -v " "
当grep找到带有空格的文件时,它返回“success”。如果-exec
中的命令成功,find
允许下一个谓词操作;但是,如果下一个运算符是“OR”的-o
,则find
仅在-exec
中的命令不成功时才允许下一个谓词操作。这就是上面的工作原理:它匹配有空格的文件,但只打印出名称不匹配的文件。(括号是必需的,以便-type f
不受“or”的约束,否则我们会得到所有非文件的内容,如目录名)。如果愿意,可以将其限制为*.js文件:
find . -type f -name '*.js' \
\( -exec grep -q '[[:space:]]' {} \; -o -print \)
值得注意的是,grep
不是检测换行符的好工具。为此,你可以考虑一些蛮力:
for file in "$d"/*.js; do
origcheck=$(md5sum < "$file")
nospacecheck=$(tr -d '[:space:]' < "$file" | md5sum)
[[ "$origcheck" = "$nospacecheck" ]] || printf '%s\n' "$file"
done
但是不要提及-L
,因此不能保证它在其他实现中会以这种方式运行。以下是一些实验:
快速健康检查:
$ grep -L '[a]' <<< 'a'
$ grep -L '[a]' <<< 'b'
(standard input)
文字“t”匹配的事实证明反斜杠-t不是grep的制表符。文字反斜杠也是一个匹配项,所以看起来表达式是由grep按面值接受的。我们知道一种表达真实标签的方法:
$ grep -L $'[ \t]' <<< $'\t'
$ grep -L $'[ \t]' <<< 't'
(standard input)
$ grep -L $'[ \t]' <<< '\'
(standard input)
上述输入字符串是否有零个或多个制表符?对他们两个都是。你只想找到一个角色,所以不要把它复杂化
但是[:space:]
呢?
你可以简单地写
find . -some -predicate -exec some command {} +
如果出于某种原因,您真的想使用xargs(也许您想利用并行化),那么告诉find和xargs文件名将用NUL字符而不是空格分隔:
find . -some -predicate -print0 | xargs -0 some command
您可能想要
[\t]+
作为第一个;每个文件都将包含与[\t]*
匹配的空字符串。这些字符串如何不起作用?您正在查找不包含空格或文件名的文件吗?我想在files@GianLucaScoccia谢谢你的澄清。为了更好地回答这个问题,我加入了一些编辑。这会查找不包含空格(可能是OP想要的)的文件名,而不是文件。另外,空格的存在(或不存在)可能是在dirname中,而不是在basename中,或者如果路径的一部分包含换行符,这也是不明确的。添加了一个查找文件的解决方案,即使文件名可能包含空格,也需要更多的引号find“$d”
,而不是find$d
,或者带有空格或glob表达式的目录名将表现不好。(另外,请参阅问题的评论:OP已澄清,他们关心的是文件内容中的空格,而不是文件名)。好消息是它可以工作,我将其标记为已接受的答案,坏消息是(以我有限的bash技能)我完全不知道它是如何工作的。要不要解释一下?我看不出比OP的原始解决方案有什么改进,也没有试图解释它是如何工作的。@tripleee Good call。已更新。
$ grep -L '[a]' <<< 'a'
$ grep -L '[a]' <<< 'b'
(standard input)
$ grep -L '[ \t]' <<< 'ab c'
$ grep -L '[ \t]' <<< $'ab\tc'
(standard input)
$ grep -L '[ \t]' <<< t
$ grep -L '[ \t]' <<< '\'
$
$ grep -L $'[ \t]' <<< $'\t'
$ grep -L $'[ \t]' <<< 't'
(standard input)
$ grep -L $'[ \t]' <<< '\'
(standard input)
$ grep -L $'[ \t]*' <<< $'\t'
$ grep -L $'[ \t]*' <<< t
$
$ grep -L '[[:space:]]' <<< ' '
$ grep -L '[[:space:]]' <<< $'\t'
$ grep -L '[[:space:]]' <<< x
(standard input)
find . -some -predicate | xargs some command
find . -some -predicate -exec some command {} +
find . -some -predicate -print0 | xargs -0 some command