查找一个扩展名与另一扩展名不匹配的文件名

查找一个扩展名与另一扩展名不匹配的文件名

我买了一台特殊的数码相机,它保存专有的图像格式,以.lri.该公司有一个桌面程序,可以将 .lri 文件渲染为标准 jpg 和 dng 文件。

我发现当我查看保存此文件的目录时,我错过了转换一些文件。然而,我能够直观地注意到丢失的文件对、文件数量和嵌套目录结构,这使得我很难确定地找到我想要转换的所有文件。

我正在寻找一个 shell 命令来查找扩展名的文件,.lri当不存在匹配的文件名时.dng(我目前不担心 jpg 文件)。例如,如果我有,如果我几个月或几年前勤奋工作,L16_04198.lri我应该有。L16_04198.dng

编辑我没有提到的两个限制: 文件位于嵌套目录结构中,因此这需要是递归搜索。另外,我的目录名称中有空格,所以它也需要能够处理这个问题。

因此,我需要一个命令或脚本来向我报告 filename L16_04198.lri,如果它在嵌套子目录结构中的任何位置找不到filename L16_04198.dng(我可能已经渲染了该文件,但将其放在错误的子目录中)。

我熟悉该find命令,但我不确定如何查找“非”文件名,并报告是否找不到该名称。

答案1

你可以试试这个:

shopt -s globstar
for f in **/*.lri; do 
  [[ ! $(find . -name "$(basename "${f%%.lri}").dng") ]] && realpath "$f"
done

答案2

长话短说:

find . -name "*.txt" | perl -nle 's/\.txt$/.foo/; print unless -e' | cat -v

这是一个使用 Perl 的示例

请注意,我们缺少 c.foo

$ ls
a.foo  a.txt  b.foo  b.txt  c.txt

我们可以这样找到

$ ls *.txt | perl -nle 's/\.txt$/.foo/; print unless -e '
c.foo

c.foo 丢失


更新:处理包含元字符等的文件名

考虑这组包含空格、换行符和管道符号的文件名

$ ls *txt
 a.txt   b.txt   c.txt  'd d.txt'  'e'$'\r''e.txt'  'f'$'\n''f.txt'  'g|g.txt'   taskmaster.txt

实际上,Perl 似乎在解析 ls 的输出时没有问题:

$ ls *txt | perl -nle 's/\.txt$/.foo/; print unless -e'
c.foo
d d.foo
e.foo
f
f.foo
g|g.foo
taskmaster.foo

显然,如果您的文件名包含控制字符,您可能需要使它们更加明显

$ ls *txt | perl -nle 's/\.txt$/.foo/; print unless -e' | cat -v
c.foo
d d.foo
e^Me.foo
f
f.foo
g|g.foo
taskmaster.foo

如果你想让它递归地工作

$ find . -name "*.txt" | perl -nle 's/\.txt$/.foo/; print unless -e' | cat -v
./c.foo
./d d.foo
./e^Me.foo
./f
f.foo
./g|g.foo
./h*h.foo
./temp/j.foo

相关内容