2017-03-05 71 views
0

所以,我在bash中有一個名爲songs_old的目錄中有好幾個文件。我想將它們複製到名稱不同的歌曲文件夾中。輸入文件的一些名稱包括:批量複製並重命名Bash中的幾個文件,使用下劃線

unknownsong_song152.mid 
town_song154.mid 
nm_battle_song158.mid 
fanfare_song159.mid 

我想在「歌曲」的結果是這樣的:

song152_unknownsong.mid 
song154_town.mid 
song158_nm_battle.mid 
song159_fanfare.mid 

我嘗試下面的代碼複製文件:

#!/bin/bash 
for i in "./songs_old/"*".mid";do mkdir -p "./songs" 
    cp "$i" "./songs/`basename "${i%.*}" | cut -d'_' -f2`_`basename "${i%.*}" | cut -d'_' -f1`.mid" 
done 

我的結果如下:

song152_unknownsong.mid 
song154_town.mid 
battle_nm.mid 
song159_fanfare.mid 

如何複製具有所需結果的文件?

回答

1

您的cp命令被傳送到cut - 這就是問題所在。你可以重寫循環是這樣的:

#!/bin/bash 
mkdir -p songs 
cd songs_old 
for i in *.mid; do 
    [[ -f "$i" ]] || continue # make sure we have a file 
    new_file=$(sed -E 's/^(.*)_(song[0-9]+).mid$/\2_\1.mid/' <<< "$i") 
    echo "Copying $i to $new_file" 
    cp "$i" "../songs/$new_file" 
done 
  • 更有意義的cd'ing到songs_old和通配符打造的「歌曲」目錄只是一次
  • ,我們消除了basename
  • 需要使用sed和正則表達式來創建新的名稱
  • 使用相對路徑../songs而拷貝

爲了您的一組文件,它給出了這樣的輸出:

Copying fanfare_song159.mid to song159_fanfare.mid 
Copying nm_battle_song158.mid to song158_nm_battle.mid 
Copying town_song154.mid to song154_town.mid 
Copying unknownsong_song152.mid to song152_unknownsong.mid 
2

使用純bash的正則表達式,你可以這樣做:

cd songs_old 
mkdir -p ../songs 

for f in *.mid; do 
    [[ $f =~ ^(.+)_([^_]+)(\.[^.]+)$ ]] && 
     cp "$f" ../songs/"${BASH_REMATCH[2]}_${BASH_REMATCH[1]}${BASH_REMATCH[3]}" 
done 

這將運行以下爲給定的樣本cp命令:

cp unknownsong_song152.mid ../songs/song152_unknownsong.mid 
cp town_song154.mid ../songs/song154_town.mid 
cp nm_battle_song158.mid ../songs/song158_nm_battle.mid 
cp fanfare_song159.mid ../songs/song159_fanfare.mid 
+1

謝謝,我意識到我的錯誤:) – anubhava