如何在find中使用参数扩展?

时间:2015-12-14 19:14:54

标签: linux

我可以使用for命令将.dat文件更改为.txt这样的文件

for f in *.dat
do
  mv $f ${f/.dat/.txt}
done

其中${f/.dat/.txt}将每个文件名中的.dat修改为.txt。但是如何使用find执行此操作?尝试使用{}作为变量失败。

find . -type f -exec echo ${} \;
-bash: ${}: bad substitution 

我可以通过将{}分配给像这样的参数

来进一步发展
find . -type f -name '*.dat'  -exec echo `f={}; echo $f` \;

但尝试替换失败

find . -type f -name '*.dat'  -exec echo `f={}; echo $(echo ${f/.dat/.txt})` \;

打印

./file1.dat
./file2.dat

./file1.txt
./file2.txt

有谁知道如何使find按照我想要的方式行事?

3 个答案:

答案 0 :(得分:1)

您可以使用awk修改文件名并生成传递给bash的cmds,即

cat fixer.awk
#!/bin/awk -f
{
        outFile=$0
        sub(/\.txt/, ".dat", outFile) ; print "mv "$0 " " outFile
}

chmod 755 fixer.awk

find . -type f -name '*.dat' | /path/to/fixer.awk

<强>输出

mv 34274841/file1.txt 34274841/file1.dat
mv 34274841/file2.txt 34274841/file2.dat

如果您对该输出感到满意,并确定没有不可预见的后果;-),那么执行

 find . -type f -name '*.dat' | /path/to/fixer.awk | bash

IHTH

答案 1 :(得分:1)

来自@celada的

This post关于systemd指向解决方案。 -exec中的find不会调用shell,因此虽然支持某些参数操作,但$f{/.dat/.txt}之类的参数扩展却不支持。

所以诀窍是执行一个shell,然后像这样逃避美元符号

find . -type f -name '*.dat'  -exec sh -c "f={}; mv \$f \${f/dat/txt}" \; 

答案 2 :(得分:0)

您可以跳过exec参数并将输出回显为sed:

find . -type f -name '*.dat' | sed 's/.dat/.txt/'