我正在尝试使用“find”对一堆HTML文件执行命令,然后将结果输出到另一个目录。但是,管道失败,因为“find”找到的文件名包含路径,并且路径不适合管道目标的目录结构。基本上我需要从下面的{}的第二个实例中删除路径。
find subd/*.html -type f -exec "./mycmd {} opts > subd2/{}" \;
这是命令的简化版本,但在现实世界中,在mysubdirectory2之前放置“../”将不起作用,也不会在“cd subd&&”之前加上前缀。
答案 0 :(得分:2)
与Jonathan的解决方案类似,但删除了不必要的额外脚本。
find subd -name '*.html' -type f -exec sh -c '
for f; do
./mycmd "$f" opts > subd2/"${f##*/}"
done
' _ {} '+'
答案 1 :(得分:1)
编写执行“正确工作”并从mycmd-invoker
运行的脚本(称之为find
)的时间:
find subd/*.html -type f -exec mycmd-invoker {} +
脚本会获得一个带路径的文件名列表,可以处理这些问题:
for file in "$@"
do
base=$(basename "$file")
./mycmd "$file" opts > subd2/"$base"
done
完成任务后,您可以抛弃mycmd-invoker
脚本,除非您认为可能需要再次执行此任务。
答案 2 :(得分:1)
这样的事情应该有效:
while read fn
do
./mycmd "${fn}" opts > "subd2/${fn##*/}"
done < <(find subd -type f -name "*.html")
答案 3 :(得分:1)
find subd/*.html -type f -exec "./mycmd {} opts > subd2/\`basename {}\`" \;
更新:在围绕基本名称
的反引号之前添加了转义符答案 4 :(得分:0)
好的,我最终找到了解决方案,即使用单引号而不是双引号,并使用$()评估表格作为basename:
find subd/*.html -type f -exec './mycmd {} opts > subd2/$(basename {})' \;
我不知道为什么单引号是差异,或者任何想法为什么Andy的解决方案在我的机器上不起作用。