如何使用 Bash 脚本将多个文件名中的所有下划线字符替换为空格?使用此代码,我们可以用破折号替换下划线。但它如何与空白一起使用?
for i in *.mp3;
do x=$(echo $i | grep '_' | sed 's/_/\-/g');
if [ -n "$x" ];
then mv $i $x;
fi;
done;
谢谢!
如何使用 Bash 脚本将多个文件名中的所有下划线字符替换为空格?使用此代码,我们可以用破折号替换下划线。但它如何与空白一起使用?
for i in *.mp3;
do x=$(echo $i | grep '_' | sed 's/_/\-/g');
if [ -n "$x" ];
then mv $i $x;
fi;
done;
谢谢!
这应该这样做:
for i in *.mp3; do
[[ "$i" = *_* ]] && mv -nv -- "$i" "${i//_/ }"
done
[[ "$i" = *_* ]]
测试文件名是否包含任何下划线,如果包含下划线,则会mv
将文件"${i//_/ }"
扩展为i
所有下划线已被空格替换的位置(请参阅shell 参数扩展)。-n
不会覆盖任何现有文件(非常安全)。可选。mv
no clobber
-v
是mv
for verbose
: 会说明它在做什么(如果你想看看发生了什么)。非常可选。--
是为了说明mv
争论将从这里开始。这始终是一个好习惯,就像文件名以 开头一样-
,mv
会尝试将其解释为一个选项,并且您的脚本将失败。很好的练习。另一条评论:当使用 glob(即for i in *.mp3
)时,设置shopt -s nullglob
或shopt -s failglob
. 如果没有文件与模式匹配,前者将*.mp3
扩展为空(因此不会执行循环),后者将显式引发错误。如果没有这些选项,如果不*.mp3
存在匹配的文件,则循环内的代码将使用可能导致问题i
的逐字值执行。*.mp3
(好吧,这里不会有任何问题,因为有 guard [[ "$i" = *_* ]]
,但是总是使用任何一个选项都是一个好习惯)。
希望这可以帮助!
您的脚本因空格而失败的原因是文件名在传递给mv
. 您需要引用文件名,以便将每个文件名视为一个单独的参数。更新脚本中的相关行:
mv "$i" "$x"
# where $i is your original filename, and $x is the new name
顺便说一句,如果您安装了perl 版本的 rename 命令,您可以跳过脚本并使用以下方法实现相同的目的:
rename 's/_/ /' *.mp3
或者,如果您有更经典的rename
命令:
rename "_" " " *.mp3
使用tr
tr '_' ' ' <file1 >file2