我正试图从名为.js
的{{1}}的任何子目录中删除所有.js.map
和src
文件。
__tests__
此操作失败,并出现以下错误:
$ find . -path './src/**' -name __tests__ | # find subdirectories
> sed -E 's/([^ ]+__tests__)/\1\/*.js \1\/*.js.map/g' | # for each subdirectory, concat *.js and *.js.map
> xargs rm # remove files
但是,如果我将rm: cannot remove './src/game/__tests__/*.js': No such file or directory
rm: cannot remove './src/game/__tests__/*.js.map': No such file or directory
rm: cannot remove './src/helpers/__tests__/*.js': No such file or directory
rm: cannot remove './src/helpers/__tests__/*.js.map': No such file or directory
更改为xargs rm
,复制并粘贴输出,然后运行它,就可以了。
xargs echo rm
将我的回声的输出包装在$ find . -path './src/**' -name __tests__ | sed -E 's/([^ ]+__tests__)/\1\/*.js \1\/*.js.map/g' |
> xargs echo rm # echo command to remove files
rm ./src/game/__tests__/*.js ./src/game/__tests__/*.js.map ./src/helpers/__tests__/*.js ./src/helpers/__tests__/*.js.map
$ rm ./src/game/__tests__/*.js ./src/game/__tests__/*.js.map ./src/helpers/__tests__/*.js ./src/helpers/__tests__/*.js.map
中并放在$(...)
前面会导致与以前相同的错误。
rm
我在做什么错了?
我怀疑这很重要,但是我正在Windows上使用GitBash。
答案 0 :(得分:2)
首先,解释问题:在find | sed | xargs rm
中,shell仅在这些程序之间建立通信,但实际上并没有以任何方式处理结果。这是一个问题,因为*.js
需要通过外壳扩展 来替换为文件名列表; rm
将给出的每个参数都当作一个文字名称。 (这与Windows不同,在Windows中,程序执行自己的命令行解析和全局扩展)。
可以说,这里根本不需要find
。考虑:
shopt -s globstar # enable ** as a recursion operator
rm ./src/**/__tests__/*.js{,.map} # delete *.js and *.js.map in any __tests__ directory under src
...或者,如果您想使用find
,请让它完成与*.js
匹配的单个文件列表的工作,而不是让这项工作稍后发生:
find src -regextype posix-egrep -regex '.*/__tests__/[^/]*[.]js([.]map)?' -delete
答案 1 :(得分:1)
您需要扩展全局(<html>
<head>
</head>
<body>
<div>
<img id="img1" src="https://cdn.silodrome.com/wp-content/uploads/2013/09/iPhone-5.jpg">
<img id="img2" src="https://i.kinja-img.com/gawker-media/image/upload/s--6tZPLps6--/c_scale,f_auto,fl_progressive,q_80,w_800/trrsg0bnoouitdhsoe0s.jpg"
</div>
</body>
</html>
)。文件名扩展由UNIX上的外壳程序执行,而不是由*
或其他程序执行。试试:
rm
...对此进行解释:
.... | xargs -d $'\n' sh -c 'IFS=; for f; do rm -- $f; done' sh
确保xargs仅在换行符(而不是空格!)上分割,并阻止其将反斜杠和引号视为特殊字符。-d $'\n'
作为脚本运行sh -c '...' sh
,其中...
作为sh
,随后的参数在$0
中,依此类推; $1
因此将遍历这些参数。for f;
清除IFS
可以防止在不加引号的情况下使用IFS=
进行字符串拆分,因此只会发生全局扩展。$f
中使用--
参数可确保将后续参数视为文件名,而不是选项,即使它们以短划线开头也是如此。也就是说,如果每个模式确实有很多文件,那么即使使用xargs,也可能会遇到“参数列表过长”的情况。
另一个警告是,包含换行符的文件名可能会拆分为多个名称(取决于您使用的rm
版本的详细信息)。可以与find
的所有POSIX兼容版本一起使用的解决此问题的方法可能是:
find