当从 Find “-exec” 调用时,管道式 Sed 不适用于 Bash 命令替换中找到的文件名

当从 Find “-exec” 调用时,管道式 Sed 不适用于 Bash 命令替换中找到的文件名

看起来“find”、“bash”和“sed”在某些情况下无法按预期工作。

以下示例应首先创建文件“sample.txt”,然后找到该文件,最后通过“-exec”命令处理它。执行的命令打印找到的文件名、测试样本和修改的文件名。 “sed”命令本身用于将“txt”替换为“TXT”。

touch sample.txt
find ./ -maxdepth 1 -name "*.txt" -exec echo {} $(echo Specimen_before.txt {} Specimen_after.txt |sed -e "s/txt/TXT/g") \;

预期输出是:

./sample.txt 样本_之前.TXT ./sample.TXT 样本_之后.TXT

相反,它会产生:

./sample.txt 样本_之前.TXT ./sample.txt 样本_之后.TXT

(该示例还通过反引号“`”使用老式命令替换进行了测试,结果相同)

我究竟做错了什么?

答案1

命令替换甚至在开始之前执行find。实际执行的命令(在替换、扩展和删除引号等之后)是

find ./ -maxdepth 1 -name *.txt -exec echo {} Specimen_before.TXT {} Specimen_after.TXT ;

如果你需要运行任何事物花哨(管道或多个命令)-exec,然后启动一个单独的 shell 来执行此操作:

find . -maxdepth 1 -type f -name '*.txt' \
    -exec sh -c 'printf "%s " "$1"; printf "%s %s %s\n" "before.txt" "$1" "after.txt" | sed "s/txt/TXT/g"' sh {} ';'

相关内容