在一堆文件中尋找共通點/模式

在一堆文件中尋找共通點/模式

比方說,我有一個包含數百或數千個文件的資料夾,所有文件均以以下架構命名:

<random number of variable length>_<date code in YYYYMMDD format>.jpg

例子:

73923_20180927.jpg
4457582_20180927.jpg
   ...
18733557_20190401.jpg
23573_20190401.jpg
   ...

我期望 bash 腳本執行的操作是列印這些日期代碼的列表,即

20180927
20190401
   ...

這聽起來像是一項更容易的任務,但實際上是一項更容易的任務。由於架構始終相同,因此我已經實作了應用字串操作,以便僅列印檔案名稱的所需部分。但是,我仍在弄清楚如何僅列印每個日期一次。

有沒有一個巧妙的方法來解決這個問題?

答案1

假設檔案名稱全部符合模式./*_*.jpg

for name in ./*_*.jpg; do
    name=${name##*_}              # 4457582_20180927.jpg --> 20180927.jpg
    printf '%s\n' "${name%.jpg}"  # 20180927.jpg --> 20180927
done | sort -u

這會迭代所有名稱。對於每個名稱,它會刪除匹配的最長前綴字串*_。然後它輸出刪除後綴的剩餘字串.jpg

然後對所有字串進行排序,以便最後只輸出唯一字串的清單。

如果存在目錄可能為空的風險,則應nullglob在循環 ( shopt -s nullglob) 之前設定 shell 選項。這將使循環根本不運行,而不是使用 中未擴展的通配模式運行一次$name


沒有特殊原因,這是如何做到這一點的sort

declare -A skip=()

for name in ./*_*.jpg; do
    key=${name##*_}    # 4457582_20180927.jpg --> 20180927.jpg
    key=${key%.jpg}    # 20180927.jpg --> 20180927
    if [[ ! -v skip[$key] ]]; then
        printf '%s\n' "$key"
        skip[$key]=1
    fi
done

在這裡,我追蹤哪些字串已作為關聯數組 中的鍵輸出skip。如果字串對應於陣列中的某個鍵,則不會輸出該字串。

答案2

假設確實沒有不正確的檔案名,則在該目錄中執行:

ls -U | awk '-F[_.]' '{ print $2 }' | sort | uniq

相關內容