2012-07-16 52 views
2

我想要一個可以在linux上使用的腳本來重命名這個表單中的文件,即雅虎巴貝爾魚 - 持久性跨站點腳本Vulnerability.jpg,該表單包含Yahoo-Babel-Fish-Persistent-Cross-Site-Scripting -Vulnerability.jpg用空格重命名文件

它只是刪除每一個空間和連字符改變它,如果它是兩個空間之間的連字符,它只是刪除了空間,就像你可以在這部分看到 「魚 - 持續」到「魚-persistent」

回答

5

由於要處理當前目錄中的所有文件,你可以在兩行做到這一點:

for f in *; do mv "$f" "$(echo $f | sed 's/ /-/g')"; done 
for f in *; do mv "$f" "$(echo $f | sed 's/---/-/g')"; done 

可能有一種方法可以在一行中完成,但目前我想不起來。

+2

+1:你可以在兩個SED表達式組合成一個單一的命令:'用sed -e 'S// -/G' -e's/---/-/g'' – 2012-07-16 00:20:55

+0

這看起來像一個非常昂貴的操作,即使只有一個'sed'。無論如何,您可以使用[herestring](http://wiki.bash-hackers.org/syntax/redirection#here_strings)而不是回顯和管道來保存一些操作。 – kojiro 2012-07-16 00:25:38

+0

謝謝你們....另一個快速的問題是,有什麼網站或書,你推薦我看看,以學習在Linux上編寫腳本? – 2012-07-16 00:31:20

1

這裏是一個純bash的解決方案,它利用了bash陣列和extglob功能優勢:

shopt -s extglob 
oIFS="$IFS" # save the original IFS 
for file in *.jpg; do # Or whatever pattern you like 
    target=(${file//+(-)/ }) # Break the filename into an array on spaces, after turning - into space. 
    IFS='-' # Temporarily set the internal field separator into a dash so we can join on dashes. 
    mv "$file" "${target[*]}" 
    IFS="$oIFS" 
done 
+0

我會用''$ {file// +([ - ])/ - }「'。 – geirha 2012-07-16 06:34:34

1
for file in *.jpg ; do file2="${file// - /-}"; file2="${file2// /-}"; echo mv "$file" "$file2" ;done 

中的回聲,如果這就是你想要的。

+0

這對於像'foo- bar.jpg'這樣的文件不起作用。你會得到'foo - bar.jpg'。 – kojiro 2012-07-16 00:46:34

+0

...它只刪除每個空格並用連字符更改它,如果它是兩個空格之間的連字符,它將僅刪除空格... – 2012-07-16 01:03:20

0

下面是我寫這篇文章時存在的三個答案的一些基準。隨意延長:

$ ./rename_bench 
setting up 
timing ext 

real 0m35.453s 
user 0m6.006s 
sys 0m27.417s 
setting up 
timing sed 

real 1m17.498s 
user 0m15.223s 
sys 0m56.376s 
setting up 
timing straight 

real 0m38.352s 
user 0m6.028s 
sys 0m28.254s 
$ ./rename_bench 
setting up 
timing ext 

real 0m36.234s 
user 0m6.030s 
sys 0m28.270s 
setting up 
timing sed 

real 1m16.467s 
user 0m15.277s 
sys 0m56.194s 
setting up 
timing straight 

real 0m33.538s 
user 0m5.911s 
sys 0m26.672s 

實際基準腳本:

#!/bin/bash 

setup() { 
    cd $(mktemp -dt "foo") && 
    touch 'a - '{0..10000}'buzz.jpg' 
} 
ext_rename() { 
    shopt -s extglob 
    oIFS="$IFS" # save the original IFS 
    for file in *.jpg; do # Or whatever pattern you like 
     target=(${file//+(-)/ }) # Break the filename into an array on spaces, after turning - into space. 
     IFS='-' # Temporarily set the internal field separator into a dash so we can join on dashes. 
     mv "$file" "${target[*]}" 
     IFS="$oIFS" 
    done 
} 

sed_rename() { 
    for f in *.jpg; do 
     mv "$f" "$(sed -e 's/ /-/g' -e 's/---/-/g' <<< "$f")" 
    done 
} 

straight_rename() { 
    for file in *.jpg; do 
     file2="${file// - /-}" 
     file2="${file2// /-}" 
     mv "$file" "$file2" 
    done 
} 

echo "setting up" 
setup 
echo "timing ext" 
time ext_rename 
echo "setting up" 
setup 
echo "timing sed" 
time sed_rename 
echo "setting up" 
setup 
echo "timing straight" 
time straight_rename