Shell-Script

查找一個副檔名的文件名與不同副檔名的文件名不匹配

  • January 14, 2021

我買了一個特殊的數位相機,它保存了一種專有的圖像格式,它以.lri. 該公司有一個桌面程序可以將 .lri 文件渲染成標準的 jpg 和 dng 文件。

我發現當我查看保存這些文件的目錄時,我錯過了轉換一些文件。但是,我能夠直覺地註意到失去的對、文件的數量和嵌套的目錄結構,這使得我很難確定地找到我想要轉換的所有文件。

.lri當不存在匹配的文件名時,我正在尋找一個 shell 命令來查找副檔名文件.dng(我目前不擔心 jpg 文件)。例如,如果我有L16_04198.lri,我應該有L16_04198.dng,如果我幾個月或幾年前工作勤奮。

編輯我沒有提到的兩個約束:文件位於嵌套目錄結構中,因此這需要進行遞歸搜尋。此外,我在目錄名稱中有空格,因此它也需要能夠處理它。

所以我需要一個命令或腳本來向我報告文件名L16_04198.lri,如果它L16_04198.dng在嵌套子目錄結構中的任何位置找到 no ,(我可能已經渲染了文件,但把它放在錯誤的子目錄中)。

我熟悉該find命令,但我不確定如何查找“非”文件名,並報告是否找不到該名稱。

tl;博士:

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

你可以試試這個:

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

引用自:https://unix.stackexchange.com/questions/628848