使用bash脚本将下划线替换为空格

时间:2012-12-19 18:23:06

标签: bash whitespace

如何使用Bash Script将所有下划线字符替换为多个文件名中的空格?使用此代码,我们可以用短划线替换下划线。但它如何与空白一起工作?

for i in *.mp3;
do x=$(echo $i | grep '_' | sed 's/_/\-/g');
if [ -n "$x" ];
then mv $i $x;
fi;
done;

谢谢!

3 个答案:

答案 0 :(得分:9)

这应该做:

for i in *.mp3; do
    [[ "$i" = *_* ]] && mv -nv -- "$i" "${i//_/ }"
done
  • 测试[[ "$i" = *_* ]]测试文件名是否包含任何下划线,如果是,则mv文件,"${i//_/ }"扩展到i所有下划线都在替换为空格(请参阅shell parameter expansions)。
  • 选项-nmv表示no clobber:不会覆盖任何现有文件(非常安全)。 可选
  • 选项-vmv适用于verbose:会说出它在做什么(如果你想看看发生了什么)。 非常可选
  • --告诉mv参数将在此处开始。这总是很好的做法,就好像文件名以-开头,mv将尝试将其解释为一个选项,并且您的脚本将失败。 非常好的练习

另一个评论:当使用globs(即for i in *.mp3)时,设置shopt -s nullglobshopt -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