sed命令修复目录中的文件名

我运行一个脚本,生成一个目录中的10K文件。 我刚刚发现脚本中有一个错误,导致一些文件名有一个回车(大概是一个'\ n'字符)。

我想运行一个sed命令来从文件名中删除回车。

任何人都知道哪些parameter passing给sed以所述的方式清理文件名?

我正在运行Linux(Ubuntu

我不知道如何sed会这样做,但这个python脚本应该做的伎俩:。

这不是sed ,但是当我做这样的事情时,我发现python更容易使用:

 #!/usr/bin/env python import os files = os.listdir('.') for file in files: os.rename(file, file.replace('\r', '').replace('\n', '')) print 'Processed ' + file.replace('\r', '').replace('\n', '') 

它从给定目录中的所有文件名中除去\r\n任何出现。

要运行它,把它保存到某个地方, cd到你的目标目录(包含要处理的文件),然后运行python /path/to/the/file.py

另外,如果你打算做更多的批量重命名,请考虑Métamorphose 。 这是一个非常好的和强大的GUI这个东西。 而且,它是免费的

祝你好运!


其实,试试这个: cd进入目录,键入python ,然后粘贴到:

 exec("import os\nfor file in os.listdir('.'):\n os.rename(file, file.replace('\\r', '').replace('\\n', ''))\n print 'Processed ' + file.replace('\\r', '').replace('\\n', '')") 

这是以前的脚本的单行版本,您不必保存它。


版本2,具有空间替换能力:

 #!/usr/bin/env python import os for file in os.listdir('.'): os.rename(file, file.replace('\r', '').replace('\n', '').replace(' ', '_') print 'Processed ' + file.replace('\r', '').replace('\n', '') 

这里是一行:

 exec("import os\nfor file in os.listdir('.'):\n os.rename(file, file.replace('\\r', '').replace('\\n', '')replace(' ', '_'))\n print 'Processed ' + file.replace('\\r', '').replace('\\n', '');") 

如果文件名中没有空格,可以这样做:

 for f in *$'\n'; do mv "$f" $f; done 

如果嵌入换行符,它将不起作用,但它将适用于换行符。

如果您必须使用sed

 for f in *$'\n'; do mv "$f" "$(echo "$f" | sed '/^$/d')"; done 

使用rename Perl脚本:

 rename 's/\n//g' *$'\n' 

或者util-linux-ng实用程序:

 rename $'\n' '' *$'\n' 

如果字符是换行符而不是换行符,请将\n^$更改为\r在上面显示的任何位置。

编辑:如果你真的想用sed ,看看这个:

沿着这些线的东西应该类似于下面的perl

 for i in *; do echo mv "$i" `echo "$i"|sed ':a;N;s/\n//;ta'`; done 

用perl,尝试一下这些内容:

 for i in *; do mv "$i" `echo "$i"|perl -pe 's/\n//g'`; done 

这将通过从当前文件夹中删除所有换行符来重命名当前文件夹中的所有文件。 如果你需要递归的话,你可以使用find ,但是在这种情况下请注意逃跑。

你没有得到任何纯粹的答案的原因是从根本上sed编辑文件内容,而不是文件名; 因此使用sed的答案都可以做一些事情,例如将文件名回显到管道(伪文件)中,使用sed编辑,然后使用mv将其转换回文件名。

由于sed已经出来了,下面是一个纯粹的bash版本,可以添加到目前为止的Perl,Python等脚本中:

 killpattern=$'[\r\n]' # remove both carriage returns and linefeeds for f in *; do if [[ "$f" == *$killpattern* ]]; then mv "$f" "${f//$killpattern/}" fi done 

…但是由于${var//pattern/replacement}在plain sh (和[[...]]一起使用),下面是一个使用sh only语法的版本, tr用来替换字符:

 for f in *; do new="$(printf %s "$f" | tr -d "\r\n")" if [ "$f" != "$new" ]; then mv "$f" "$new" fi done 

实际上有一种使用sed的方法:

 carr='\n' # specify carriage return files=( $(ls -f) ) # array of files in current dir for i in ${files[@]} do if [[ -n $(echo "$i" | grep $carr) ]] # filenames with carriage return then mv "$i" "$(echo "$i" | sed 's/\\n//g')" # move! fi done 

这实际上起作用。