bash 從檔案名稱中提取第一個數字

bash 從檔案名稱中提取第一個數字

我正在嘗試像這樣移動文件:

...
DLG023-00-01-sprite.TextGrid.json
DLG023-00-01.prosody.json
DLG023-01-01-sprite.ogg
DLG023-00-02-sprite.TextGrid.json
DLG023-00-02.prosody.json
DLG023-01-02-sprite.ogg
...
DLG028-00-01-sprite.TextGrid.json
DLG028-00-01.prosody.json
DLG028-01-01-sprite.ogg
...

進入各自的資料夾,例如:將檔案移到以;dialogue023/開頭的位置DLG023到以;dialogue024/開頭的時間DLG024等等。

所有檔案和目錄都處於同一層級。

換句話說,我正在嘗試產生這樣的命令:

mv DLG023-00-01-sprite.ogg dialogue023/

如何從檔案名稱中提取第一個數字?

到目前為止我已經得到了這個:

for i in DLG*-*-*-sprite.ogg; do echo "${i//[^0-9]}";done

但是當我只想要第一個數字(例如:23)時,這會輸出所有數字(例如:230001)。

答案1

我假設您使用的是 OS X,它-t沒有mv.如果腳本正在處理數千個文件,這將非常緩慢。

    for file in DLG*; do
    # Extract the three digits after DLG
    getnum=${file%%-*}
    getnum=${getnum#???}

    # make the directory dialogue### or exit if there is an error
    echo mkdir -p "dialogue${getnum}" || exit

    echo mv "$file" "dialogue${getnum}"
    done

如果輸出令人滿意,則刪除echo先前的mkdir和。mv

答案2

您可以使用以下命令產生 mv 命令:

for f in DLG*; do echo "$f" | sed 's/DLG\([0-9]\+\).*/mv "\0" "dialogue\1\/"/g'; done

現在,命令列印如下:

mv "DLG023-00-01.prosody.json" "dialogue023/"
[...]
mv "DLG028-00-01.prosody.json" "dialogue028/"
[...]

如果這是你想要的,只需將該輸出通過管道傳遞到bash它就會被執行:

for f in DLG*; do echo "$f" | sed 's/DLG\([0-9]\+\).*/mv "\0" "dialogue\1\/"/g'; done | bash

答案3

一行解決方案使用find

find . -name DLG* -exec bash -c 'DEST=$(echo "$0" | sed -r "s/DLG([0-9]+)-.*/dialogue\1/"); mkdir "$DEST"; mv "$0" "$DEST"' {} \;
  • findDLG*命令從此目錄中尋找檔案。
  • 對於每個結果執行bash -c句子。

句子中bash

  • DEST=$(echo "$0" | sed -r "s/DLG([0-9]+)-.*/dialogue\1/");從 find ( $0) 中選取每個結果,並使用sed將第一個-(DLG([0-9]+)-.*) 之前的所有數字替換為dialogue後面的這些數字 ( dialogue\1) 並放入名為 的變數中DEST
  • mkdir "$DEST"建立所需的資料夾。
  • mv "$0" "$DEST"'將檔案移動到該目錄。

答案4

幾個想法:

for i in DLG*-\*-\*-sprite.ogg; do echo "${i//[^0-9]}" | head -c 2; echo ;done

如果您確定它們的長度都相同:

for i in DLG*-\*-\*-sprite.ogg; do echo "${i:3:3}" ;done

相關內容