我运行一个脚本,生成一个目录中的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
这实际上起作用。