![查找一个扩展名与另一扩展名不匹配的文件名](https://linux22.com/image/186370/%E6%9F%A5%E6%89%BE%E4%B8%80%E4%B8%AA%E6%89%A9%E5%B1%95%E5%90%8D%E4%B8%8E%E5%8F%A6%E4%B8%80%E6%89%A9%E5%B1%95%E5%90%8D%E4%B8%8D%E5%8C%B9%E9%85%8D%E7%9A%84%E6%96%87%E4%BB%B6%E5%90%8D.png)
我买了一台特殊的数码相机,它保存专有的图像格式,以.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