
我想將具有以下副檔名的檔案重新命名:.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
。