简体   繁体   English

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

[英]Replace underscores to whitespaces using bash script

How can I replace all underscore chars with a whitespace in multiple file names using Bash Script? 如何使用Bash Script在多个文件名中用空格替换所有下划线字符? Using this code we can replace underscore with dash. 使用此代码,我们可以将下划线替换为破折号。 But how it works with whitespace? 但是它如何与空白一起使用?

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

Thank you! 谢谢!

This should do: 应该这样做:

for i in *.mp3; do
    [[ "$i" = *_* ]] && mv -nv -- "$i" "${i//_/ }"
done
  • The test [[ "$i" = *_* ]] tests if file name contains any underscore and if it does, will mv the file, where "${i//_/ }" expands to i where all the underscores have been replaced with a space (see shell parameter expansions ). 测试[[ "$i" = *_* ]]测试,如果文件名包含任何下划线,如果这样做,将mv的文件,其中"${i//_/ }"扩展到i ,所有的下划线有被空格代替(请参阅shell参数扩展 )。
  • The option -n to mv means no clobber : will not overwrite any existent file (quite safe). mv的选项-n表示no clobber :不会覆盖任何存在的文件(相当安全)。 Optional . 可选的
  • The option -v to mv is for verbose : will say what it's doing (if you want to see what's happening). 选项-vmvverbose :会说出它在做什么(如果您想看看正在发生什么)。 Very optional . 非常可选
  • The -- is here to tell mv that the arguments will start right here. --是在这里告诉mv参数将从此处开始。 This is always good practice, as if a file name starts with a - , mv will try to interpret it as an option, and your script will fail. 这始终是一个好习惯,就像文件名以-开头时, mv会尝试将其解释为选项,并且脚本将失败。 Very good practice . 很好的做法

Another comment: When using globs (ie, for i in *.mp3 ), it's always very good to either set shopt -s nullglob or shopt -s failglob . 另一条评论:使用glob时(例如, for i in *.mp3 ),设置shopt -s nullglobshopt -s failglob总是很好。 The former will make *.mp3 expand to nothing if no files match the pattern (so the loop will not be executed), the latter will explicitly raise an error. 如果没有文件与模式匹配,前者将使*.mp3扩展为*.mp3 (因此不会执行循环),后者将显式引发错误。 Without these options, if no files matching *.mp3 are present, the code inside loop will be executed with i having the verbatim value *.mp3 which can cause problems. 如果没有这些选项,如果不存在与*.mp3匹配的文件,则将使用i的逐字值*.mp3执行循环内的代码,这可能会导致问题。 (well, there won't be any problems here because of the guard [[ "$i" = *_* ]] , but it's a good habit to always use either option). (好吧,由于守护[[ "$i" = *_* ]] ,在这里不会有任何问题,但是始终使用这两个选项是一个好习惯)。

Hope this helps! 希望这可以帮助!

The reason your script is failing with spaces is that the filename gets treated as multiple arguments when passed to mv . 您的脚本使用空格失败的原因是,传递给mv时,文件名被视为多个参数。 You'll need to quote the filenames so that each filename is treated as a single agrument. 您需要引用文件名,以便将每个文件名视为一个单独的文件。 Update the relevant line in your script with: 使用以下命令更新脚本中的相关行:

mv "$i" "$x"  
# where $i is your original filename, and $x is the new name

As an aside, if you have the perl version of the rename command installed, you skip the script and achieve the same thing using: 顺便说一句,如果您安装了重命名命令perl版本,则可以跳过该脚本并使用以下命令完成相同的操作:

rename 's/_/ /' *.mp3

Or if you have the more classic rename command : 或者,如果您拥有更经典的rename命令

rename "_" " " *.mp3

使用tr

tr '_' ' ' <file1 >file2

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM