2015-10-10 76 views
2

我正在嘗試在重命名腳本中將連續的四位數字添加到文件名的末尾。我遇到的問題是,它只填充第一個文件,添加的數字不是順序的。這裏是我的腳本至今:在文件名的末尾添加連續數字 - Shell腳本

開始的文件名:

FILE-1.png 
FILE-5.png 
FILE-14.png 
FILE-99.png 
FILE-167.png 
FILE-199.png 
FILE-278.png 
FILE-455.png 

腳本:

a=`printf '%04d' "1"` 

cd /${1-$PWD} 

for i in *.png; 
    do mv $i `printf output.%04d.$a.png $(echo $i | sed 's/[^0-9]*//g')`; 
    let a=a+1 
done 

編輯: 我改劇本有點納入頂部的fmt變量。但我仍然希望它按照第一組數字的數字順序來命名第二組數字,如下面的我希望的輸出中所示。

fmt=output.%04d 
n=1 

cd /${1-$PWD} 

for i in *.png; 
    do mv $i `printf $fmt.%04d.png $(echo $i | sed 's/[^0-9]*//g') "$n"`; 
    n=$((n+1)) 
done 

我的新的輸出:

output.0001.0001.png 
output.0005.0007.png 
output.0014.0002.png 
output.0099.0008.png 
output.0167.0003.png 
output.0199.0004.png 
output.0278.0005.png 
output.0455.0006.png 

原始輸出:

output.0001.0001.png 
output.0005.7.png 
output.0014.2.png 
output.0099.8.png 
output.0167.3.png 
output.0199.4.png 
output.0278.5.png 
output.0455.6.png 

所需的輸出:

output.0001.0001.png 
output.0005.0002.png 
output.0014.0003.png 
output.0099.0004.png 
output.0167.0005.png 
output.0199.0006.png 
output.0278.0007.png 
output.0455.0008.png 

一如往常的任何幫助深表感謝!

+2

不知道爲什麼有人低估了這一點。它具有一個好問題的所有要素 - 輸入,期望和實際輸出,甚至嘗試編碼解決方案。 – ghoti

回答

1

所以..你使用printf進行格式化。這是一個好的開始。但是你沒有持續使用它。沒有格式化的部分..爲什麼不只是格式化呢?

#!/bin/sh 

fmt="output.%04d.%04d.png" 

cd /${1-$PWD} 

n=1 
for file in *.png; do 
    fn="${file%.*}"; fn="${fn#*-}" 
    mv "$file" "$(printf "$fmt" "$fn" "$n")" 
    n=$((n+1)) 
done 

注意循環中的第一行簡單地脫掉一切從點到終點,然後通過從開始到儀表板起飛的一切剝離數出$file,第一。如果您的文件沒有按照您的問題進行實際格式化,則必須調整此設置。

哦,感恩節快樂。 :-)每評論


UPDATE

以上的*.png顯然會責令按字母順序的東西,這樣你FILE-5.png如下FILE-455.png擴展等

有許多工具可以幫助你獲得「自然」排序順序。特別是,如果您使用Linux,您的lssort可能來自GNU coreutils,這意味着您可以使用ls -vsort -V來獲得自然排序順序。但是你沒有指定你在使用Linux,除此之外,還有parsing ls is a bad idea。但是bash的內部模式匹配和路徑名擴展並不能處理自然類型。

這種特殊情況下,因爲你正在處理(至少在你的問題)具有高度可預測格式的文件名,我們可以放心地可能解析ls輸出,並使用命令行工具排序。

shopt -s extglob 
ls -v FILE-+([0-9]).png | while read file; do 

這臺bash的extglob外殼選項,然後使用ls -v(這是Linux的相關性)來顯示限制:

如果你正在使用Linux和bash,上面for線可以被替換文件的視圖。在解析ls時,您不想因爲*.png這樣的結構出錯,因爲您不需要花時間預測文件名中是否存在換行符會發生什麼情況。

如果你使用的是FreeBSD或OSX,或者不使用bash,需要額外的措施,因爲有ls -v和Almquish外殼沒有extglob

ls -f FILE-*.png | egrep '^FILE-[0-9]+\.png$' | sort -t- -k2n | while read file; do 
    if [ ! -f "$file" ]; then 
    continue 
    fi 

這種分解如下:

  • ls -f確實目錄上的排序。 filespec有點限制了這個視圖。
  • grep用於強制執行文件名格式,因爲此模式不能在shell擴展中完全表示。
  • sort -t- -k2n用連字符分隔字段,然後在第二個字段上進行數字排序。
  • 循環內部的if確保我們有人不會通過創建像FILE-1.png\nFILE-2.png這樣的文件名來搞砸我們。
+0

感謝您的幫助,但它似乎沒有按照要求工作。在第10行中,我實際上切換了「$ n」和「$ fn」的順序,但是得到了這個: 'output.0001.testing4d.pngoutput.0001.testing4d.png' 請注意腳本另存爲testing.sh所以它將腳本名稱以某種方式併入重命名中。 – VanCityGuy

+0

另一件事是它不是讓他們連續: 'output.0001.testing4d.pngoutput.0001.testing4d.png' 'output.0005.testing4d.pngoutput.0007.testing4d.png' 'output.0014。 testing4d.pngoutput.0002.testing4d.png' 'output.0099.testing4d.pngoutput.0008.testing4d.png' 'output.0167.testing4d.pngoutput.0003.testing4d.png' 'output.0199.testing4d。 pngoutput.0004.testing4d.png' 'output.0278.testing4d.pngoutput.0005.testing4d.png' 'output.0455.testing4d.pngoutput.0006.testing4d.png' – VanCityGuy

+1

'fmt = '在我已經修復的腳本的頂部的一行;第二個'%'被替換爲'$'。幾天來一直沒有找到我的眼鏡,抱歉讓我感到困惑。不確定發生了什麼事,這是順序的; 'for'行上的路徑名擴展,'* .png'應該按字母/數字順序匹配文件。再次嘗試修復'fmt'行,看看結果是否如你所期望的那樣。 – ghoti

相關問題