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