2

我正在尝试使用“查找”对一堆 HTML 文件执行命令,然后将结果通过管道输出到不同的目录。但是,管道失败是因为“find”找到的文件名包含路径,并且路径不适合管道目标的目录结构。本质上,我需要从下面的 {} 的第二个实例中删除路径。

find subd/*.html -type f -exec "./mycmd {} opts > subd2/{}" \;

这是命令的简化版本,但在现实世界中,在 mysubdirectory2 之前放置“../”将不起作用,前缀“cd subd &&”也不起作用。

4

5 回答 5

2

类似于 Jonathan 的解决方案,但删除了不必要的额外脚本。

find subd -name '*.html' -type f -exec sh -c '
    for f; do
        ./mycmd "$f" opts > subd2/"${f##*/}"
    done
' _ {} '+'
于 2013-03-25T21:21:55.137 回答
1
find subd/*.html -type f -exec "./mycmd {} opts > subd2/\`basename {}\`" \;

更新:在 basename 周围的反引号之前添加了转义

于 2013-03-25T17:17:34.877 回答
1

像这样的东西应该可以工作:

while read fn
do
  ./mycmd "${fn}" opts > "subd2/${fn##*/}"
done < <(find subd -type f -name "*.html")
于 2013-03-25T17:12:29.033 回答
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脚本,除非您认为可能需要再次执行。

于 2013-03-25T16:49:02.033 回答
0

好的,我最终找到了解决方案,就是使用单引号而不是双引号,并对basename使用$()评估表:

find subd/*.html -type f -exec './mycmd {} opts > subd2/$(basename {})' \;

我不知道为什么单引号会有所不同,也不知道为什么安迪的解决方案在我的机器上不起作用。

于 2013-03-26T10:32:59.290 回答