使用 grep 和 for 重新命名文件

使用 grep 和 for 重新命名文件

我想將具有以下副檔名的檔案重新命名:.txt、.data、.conf 至“.xml”

你好.txt -> 你好.xml

為此,文件還必須包含以下行:<?xml version="1.0" encoding="UTF-8"?>

這就是我所擁有的:

for file in *
do
if [ $(grep -Rc '<?xml version="1.0" encoding="UTF-8"?>' --include ".txt" --include ".data" --include "*.conf") = true ]
then
rename extension to: .xml
fi
done

有任何想法嗎?

答案1

如果你需要這樣做grep然後for也許是這樣的?

grep -RlZ '<?xml version="1.0" encoding="UTF-8"?>' --include "*.txt" --include "*.data" --include "*.conf" | 
  xargs -0 sh -c 'for f; do echo mv -- "$f" "${f%.*}.xml"; done' sh

echo一旦您確信它正在做正確的事情,請刪除)。

  • grep -RlZ輸出找到匹配項的檔案名稱的空分隔列表

  • xargs -0將該空分隔清單傳遞給sh -c

  • for f將檔案名稱作為位置參數循環

或者(如果允許您使用while而不是for)您可以跳過xargs和附加的 shell scriptlet,例如

grep -RlZ '<?xml version="1.0" encoding="UTF-8"?>' --include "*.txt" --include "*.data" --include "*.conf" | 
  while IFS= read -r -d '' f; do echo mv -- "$f" "${f%.*}.xml"; done

答案2

find . -type f \( -name "*.txt" -o -name "*.data" -o -name "*.conf" \) -exec sh -c '
    for file in "$@"; do
        if grep -qF "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" "$file"; then
            mv -- "$file" "${file%.*}.xml"
        fi
    done
' findshell {} +

我認為find在這種情況下更合適。它遞歸地查找帶有.txt,.data.conf擴展名的常規文件,並檢查您提供的字串是否存在於每個文件中。如果是,那麼它將.xml透過命令將擴展名更改為mv

如果您不確定程式碼是否會如預期運作,您可以在echo前面新增一個mv以查看它的作用。

我還應該提到該腳本不依賴非 POSIX 實用程式。

答案3

你可以試試這個:

for file in *.{txt,conf}; do 
  [[ $(grep "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" "$file") ]] && \
  mv "$file" "${file%.*}.xml" || echo "$file" " does not match"
done

答案4

使用bash

shopt -s globstar dotglob nullglob extglob

string='<?xml version="1.0" encoding="UTF-8"?>'

for pathname in ./**/*.@(txt|data|conf); do
    if [[ -f $pathname ]] && grep -q -F "$string" "$pathname"; then
        mv -i "$pathname" "${pathname%.*}.xml"
    fi
done

我先設定一些預設通常不會設定的 shell 選項bash

  • globstar啟用**遞歸匹配子目錄的通配模式。
  • dotglob使通配模式與隱藏名稱相符。
  • nullglob使不匹配的模式完全消失,而不是保持未展開狀態。這確保瞭如果沒有匹配,我們的循環稍後將不會運行。
  • extglob啟用擴充的通配模式,例如@(txt|data|conf)符合括號內的字串之一。

然後,我們循環遍歷候選名稱並測試每個名稱的給定字串。如果找到該字串,則透過將最後一個點字元後面的檔案名稱後綴替換為 來重新命名該檔案xml

相關內容