有沒有辦法在不使用正則運算式的情況下重命名包含以下約定命名的檔案的目錄?舉例來說,我有一個名為檔案1.json,2.json,3.json,4.json,我希望他們都改名為他們目前#{NUM}對#{NUM - 1}這樣的結果集將是:0.json,1.json,2.json,3.json。
使用約定:
for i in *.json; do mv -- "$i" ..
沒有正則運算式可以做到這一點嗎?還是我一直在決議檔案名,將字串轉換為整數并從那里開始?
uj5u.com熱心網友回復:
${var%suffix}將洗掉尾隨后綴。您可以使用它來剝離.json并獲取數字。
for file in *.json; do
i="${file%.json}"
echo mv -- "$i".json "$((i-1))".json
done
echo如果看起來不錯,請洗掉它。
請注意,這只會處理一位數的檔案名。要處理多位檔案名,我們需要讓它們自然排序而不是按字典順序排序。字典排序 put 10before9因為字符1小于9,意思是10.json將被重命名為9.jsonbefore9.json被重命名為8.json。自然排序,通過對比,將整理9之前10。
可悲的是,這使整個事情變得更加神秘十倍。Glob 不能行內排序,因此我們必須四處移動,以便我們可以將檔案名串列通過管道傳輸到sort -g. 然后要回圈檔案名流,我們必須從for回圈更改為while read帶有行程替換的回圈。
基本骨架結構如下所示:
while read file; do
...
done < <(ls *.json | sort -g)
然后我們將進行一些改進:
使用
while IFS= read -r使分析更穩健。通過切換到基于 - 的技術來列印檔案名來避免決議
lsprintf。使用 NUL 分隔符而不是換行符,因為換行符在技術上是檔案名中的合法字符。這意味著添加
\0到printf,-z到sort,并-d $'\0'以read獲得每三個發射和消費完全無效。
這些步驟是良好的一般習慣,但我承認它們對于這個特定的腳本并不是非常重要,它們使代碼看起來像弗蘭肯斯坦的怪物。我在這里展示它們是出于教學目的。我不會告訴您是否將它們從一次性個人使用腳本中洗掉。
最終的、強大的解決方案:
while IFS= read -rd $'\0' file; do
i="${file%.json}"
echo mv -- "$i".json "$((i-1))".json
done < <(printf '%s\0' *.json | sort -zg)
uj5u.com熱心網友回復:
您可以使用awk基于此的解決方案:
printf '%s\n' [1-9]*.json | sort -n |
awk -F. '{print "mv", $0, ($1-1 FS $2)}' | bash
mv 1.json 0.json
mv 2.json 1.json
mv 3.json 2.json
mv 4.json 3.json
mv 5.json 4.json
一旦您對輸出感到滿意,您就可以洗掉echobefore mv。
uj5u.com熱心網友回復:
試試這個代碼。來自檔案名的 -1 簡單。但是如果你的檔案名在名字中包含零,假設001.json..n 那么有1.json,這個代碼將不起作用。因為它將替換當前1.json檔案
declare -i newName=0
for i in `ls | sort -n | grep ".json"`
do
newName=${i%%.*}-1
mv -- "$i" "$newName.json"
done
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/346503.html
下一篇:查找文本中出現的字串并提取值
