所以,我在bash的一个名为songs_old的目录中有几个文件。我想将它们复制到名为带有不同名称的歌曲的文件夹中。输入文件的某些名称包括:
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
如何复制具有所需结果的文件?
答案 0 :(得分: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 :(得分: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
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