我有下一個問題:
目錄Example1
包含三個檔案:Example1
、Things
和Pictures
。
目錄Example2
包含三個檔案:Example2
、Example3
和Pictures
。
我需要一個僅顯示與目錄名稱匹配的文件的列表,這是:Example1
和Example2
。我嘗試過 diff、find、locate 和 ls...但我沒有任何成果。
答案1
您可以使用反向引用輕鬆地將與包含目錄同名的檔案名稱與正規表示式相符。這些是what/ever/something/something
兩個something
部分相同且不包含斜杠的形式的檔案名稱。在 BRE 正規表示式語法中,[^/]*
匹配任何不包含斜杠的字串,\(/[^/]*\)
匹配斜杠後跟任意數量的非斜杠字符並使整個事物成為一個組,並\1
匹配與第一個組匹配的相同文本,因此\(/[^/]*\)\1
符合兩個具有相同名稱的路徑段。.*
在開頭新增以符合先前的目錄組件。
使用 GNU find、FreeBSD find、macOS find 或任何其他find
支援的-regex
:
find . -regex '.*\(/[^/]*\)\1'
答案2
由於目錄通常比檔案少,因此我們會尋找所有目錄,然後測試它們是否包含所需的檔案名稱。
find . -type d -exec sh -c '
for dirpath do
filepath="$dirpath/${dirpath##*/}"
[ -f "$filepath" ] && printf "%s\n" "$filepath"
done' sh {} +
這將列印位於與該檔案同名的目錄中的所有常規檔案(以及常規檔案的符號連結)的路徑名稱。
該測試是在一個簡短的內聯sh -c
腳本中完成的,該腳本將獲取許多目錄路徑名作為參數。它迭代每個目錄路徑名並使用我們正在尋找的名稱來建構一個檔案路徑名。${dirpath##*/}
代碼中的 可以替換為$(basename "$dirpath")
.
對於給定的範例目錄結構,這將輸出
./Example1/Example1
./Example2/Example2
只是測試任何名字,不只是常規文件,把-f
測試改成-e
測試。
答案3
使用find -exec
:
find . -type f \
-exec sh -c '[ "$(basename "$1")" = "$(basename "$(dirname "$1")")" ]' find-sh {} \; \
-print
僅當內部-print
結果為 true 時才會執行。[ ... ]
-exec sh -c '...'
輸出:
./Example1/Example1
./Example2/Example2