Find
僅查找包含與文件夾同名的文件的文件夾
我想找到所有包含同名(和副檔名
.md
)的降價文件的子文件夾。例如:我想查找以下子文件夾:
Apple/Banana/Orange #Apple/Banana/Orange/Orange.md exists Apple/Banana #Apple/Banana/Banana.md exists Apple/Banana/Papaya #Apple/Banana/Papaya/Papaya.md exists
- 注意:目錄中可以有其他文件或子目錄。
有什麼建議麼?
可以使用以下程式碼測試問題的解決方案:
#!/usr/bin/env bash # - goal: "Test" # - author: Nikhil Agarwal # - date: Wednesday, August 07, 2019 # - status: P T' (P: Prototyping, T: Tested) # - usage: ./Test.sh # - include: # 1. # - refer: # 1. [directory - Find only those folders that contain a File with the same name as the Folder - Unix & Linux Stack Exchange](https://unix.stackexchange.com/questions/534190/find-only-those-folders-that-contain-a-file-with-the-same-name-as-the-folder) # - formatting: # shellcheck disable= #clear main() { TestData ExpectedOutput TestFunction "${1:?"Please enter a test number, as the first argument, to be executed!"}" } TestFunction() { echo "Test Function" echo "=============" "Test${1}" echo "" } Test1() { echo "Description: Thor" find . -type f -regextype egrep -regex '.*/([^/]+)/\1\.md$' | sort echo "Observation: ${Green:=}Pass, but shows filepath instead of directory path${Normal:=}" } Test2() { echo "Description: Kusalananda1" find . -type d -exec sh -c ' dirpath=$1 set -- "$dirpath"/*.md [ -f "$dirpath/${dirpath##*/}.md" ] && [ "$#" -eq 1 ]' sh {} \; -print | sort echo "Observation: ${Red:=}Fails as it ignores B.md${Normal:=}" } Test3() { echo "Description: Kusalananda2" find . -type d -exec sh -c ' for dirpath do set -- "$dirpath"/*.md if [ -f "$dirpath/${dirpath##*/}.md" ] && [ "$#" -eq 1 ] then printf "%s\n" "$dirpath" fi done' sh {} + | sort echo "Observation: ${Red:=}Fails as it ignores B.md${Normal:=}" } Test4() { echo "Description: steeldriver1" find . -type d -exec sh -c '[ -f "$1/${1##*/}.md" ]' find-sh {} \; -print | sort echo "Observation: ${Green:=}Pass${Normal:=}" } Test5() { echo "Description: steeldriver2" find . -type d -exec sh -c ' for d do [ -f "$d/${d##*/}.md" ] && printf "%s\n" "$d" done' find-sh {} + | sort echo "Observation: ${Green:=}Pass${Normal:=}" } Test6() { echo "Description: Stéphane Chazelas" find . -name '*.md' -print0 \ | gawk -v RS='\0' -F/ -v OFS=/ ' {filename = $NF; NF-- if ($(NF)".md" == filename) include[$0] else exclude[$0] } END {for (i in include) if (!(i in exclude)) print i}' echo "Observation: ${Red:=}Fails as it ignores B.md${Normal:=}" } Test7() { echo "Description: Zach" #shellcheck disable=2044 for fd in $(find . -type d); do dir=${fd##*/} if [ -f "${fd}/${dir}.md" ]; then ls "${fd}/${dir}.md" fi done echo "Observation: ${Green:=}Pass but shows filepath instead of directory${Normal:=}" } ExpectedOutput() { echo "Expected Output" echo "===============" cat << EOT ./GeneratedTest/A ./GeneratedTest/A/AA ./GeneratedTest/B ./GeneratedTest/C/CC1 ./GeneratedTest/C/CC2 EOT } TestData() { rm -rf GeneratedTest mkdir -p GeneratedTest/A/AA touch GeneratedTest/index.md touch GeneratedTest/A/A.md touch GeneratedTest/A/AA/AA.md mkdir -p GeneratedTest/B touch GeneratedTest/B/B.md touch GeneratedTest/B/index.md mkdir -p GeneratedTest/C/CC1 touch GeneratedTest/C/index.md touch GeneratedTest/C/CC1/CC1.md mkdir -p GeneratedTest/C/CC2 touch GeneratedTest/C/CC2/CC2.md mkdir -p GeneratedTest/C/CC3 touch GeneratedTest/C/CC3/CC.md mkdir -p GeneratedTest/C/CC4 } main "$@"
假設您的文件命名合理,即不需要
-print0
等。您可以使用 GNU find 執行此操作,如下所示:find . -type f -regextype egrep -regex '.*/([^/]+)/\1\.md$'
輸出:
./Apple/Banana/Orange/Orange.md ./Apple/Banana/Papaya/Papaya.md ./Apple/Banana/Banana.md
如果您只想要目錄名稱,請添加一個
-printf
參數:find . -type f -regextype egrep -regex '.*/([^/]+)/\1\.md$' -printf '%h\n'
在更新的測試數據上執行時的輸出:
GeneratedTest/A/AA GeneratedTest/A GeneratedTest/C/CC2 GeneratedTest/C/CC1 GeneratedTest/B