我有一个问题,我想从find
命令中找到每条路径的长度。我的第一次尝试是运行这样的东西:
find . -exec sh -c "echo {} | wc -c" \;
我从这个答案中得到了这个想法。(上面的命令不是我的问题,我只是用它作为一个例子,它完全是人为的。另外,有时我可能需要多个管道。)
但是当我运行它时,输出中有错误,可能是由于输出路径中的特殊字符。不幸的是,我不知道哪些路径导致了问题,并且错误消息没有提供信息。不管...
find
命令直接执行命令。该命令(包括文件名参数)不会被 shell 或任何其他可能修改文件名的东西处理。这是非常安全的。
这似乎很方便。事实上,如此方便,以至于-exec sh -c ...
“治愈”似乎比疾病更糟糕。
所以我的问题是,当我需要使用管道命令find
并且我的路径可能包含特殊字符时,我该怎么办?这个问题是否有一个通用的解决方案,我不必考虑一堆警告?我正在使用 bash。
注意:这是一个类似的问题:如何最好地将 find + exec 命令的输出发送到管道?不同之处在于,我不一定要尝试将输出输出到-exec
. 即,如果find ... -exec ... foo {} | bar \;
是要走的路,那对我来说很好。我只是在寻找阻力最小的通用路径,命令的结构对我来说并不重要。
将文件名作为参数传递给 shell 脚本:
或者对于每个 shell 调用的多个文件:
你的命令
将在 shell 命令行上按原样插入文件名。它仅适用于不包含空格或 shell 特殊字符的文件名。例如,类似 a 的东西
Don't stop me now.mp3
会this&that.txt
导致问题。(第一个会产生一个未终止的带引号的字符串,第二个会echo
在后台开始,然后尝试运行一个名为that.txt
.)另一方面,
sh -c ... sh {} \;
(或... {} +
已将find
文件名作为不同的参数传递给 shell,然后它们将在位置参数中可用,并且可以在不与 shell 语法混合的情况下使用它们。("$1"
对于第一个,"$@"
对于整个列表。记住引号。)对于检查文件名长度的情况,您也可以
"${#var}"
在 shell 中获取它,除了它根据当前语言环境给出字符wc -c
长度,同时计算字节数。即使
-exec echo {}
避免了shell处理,许多版本的echo mangle 参数都包含反斜杠或前导连字符。(当然,它不会wc
按照您的意愿进行传输。)我不会为每个路径名执行,而是
wc
使用一个旨在处理多个输入行(即记录)的程序:或者
perl -nle 'print length'
默认为字节,但我看不到处理这种-print0
情况以允许换行符的方法。