Bash

從具有特定副檔名的所有文件中遞歸刪除副檔名

  • July 20, 2021

我有一個包含一堆子目錄的目錄,其中包含一堆副檔名為.no_sub.

我想將每個帶有副檔名的文件重命名.no_sub為同名並.no_sub刪除。

所以foo.no_sub-> foo

我可以在 Bash 中執行此操作嗎?(我在 Ubuntu 20.04 上)

使用 shell 的強大功能獲取所有文件,然後使用常用工具重命名它們

shopt -s nullglob ## as recommended and explained in the comments
shopt -s globstar
shopt -s dotglob
for fname in **/*.no_sub ; do
 mv -- "${fname}" "${fname%.no_sub}"
done

這裡,

  • shopt -s globstar``**作為遞歸全域啟用
  • shopt -s dotglob可以找到.*.no_sub
  • 循環是一種遍歷所有文件的for特殊字元安全方式(永遠不要解析ls
  • mv語法mv source target是;
  • 我有時過於小心,但我也喜歡${fname}不只是$fname,因為不會有變數名混淆。它只是擴展到變數的內容fname,即目前文件
  • 變數擴展${variable%pattern}擴展為變數內容,但被後綴模式縮減pattern

使用標準findshmv

find . -type f -name '*.no_sub' -exec sh -c '
   for pathname do
       mv -- "$pathname" "${pathname%.no_sub}"
   done' sh {} +

這將查找名稱以 string 結尾的任何正常文件,.no_sub位於目前目錄中或目前目錄下。對於這些路徑名的批次,呼叫一個簡短的內嵌 shell 腳本。此sh -c腳本遍歷給定的一批路徑名,並通過刪除.no_sub文件名後綴重命名它們中的每一個。使用標準${variable%suffix}參數擴展來刪除文件名後綴。

不檢查文件名衝突。

類似於Marcus Müller 提供的解決方案,因為單個文件的重命名以相同的方式發生,但用於find生成循環的路徑名列表,其方式將獲取隱藏名稱並包含顯式文件類型過濾器僅迭代正常文件。

另請參閱:了解 find 的 -exec 選項


由於我們知道賦予內聯腳本的每個文件名都以 結尾,因此如果我們願意.no_sub,我們可以避免在其中重複:.no_sub

find . -type f -name '*.no_sub' -exec sh -c '
   for pathname do
       mv -- "$pathname" "${pathname%.*}"
   done' sh {} +

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