Bash sed命令修复目录中的文件名
我运行了一个脚本,在一个目录中生成了大约10k个文件。我刚刚发现脚本中有一个bug,它导致一些文件名带有回车符(可能是'\n'字符) 我想运行sed命令从文件名中删除回车符 有人知道应该将哪些参数传递给sed,以便以所描述的方式清理文件名吗Bash sed命令修复目录中的文件名,bash,ubuntu,sed,Bash,Ubuntu,Sed,我运行了一个脚本,在一个目录中生成了大约10k个文件。我刚刚发现脚本中有一个bug,它导致一些文件名带有回车符(可能是'\n'字符) 我想运行sed命令从文件名中删除回车符 有人知道应该将哪些参数传递给sed,以便以所描述的方式清理文件名吗 我正在运行Linux(Ubuntu)编辑:如果您真的想使用sedsed,请查看以下内容: 这方面的工作应该与下面的perl类似: for i in *; do echo mv "$i" `echo "$i"|sed ':a;N;s/\n//;ta'`;
我正在运行Linux(Ubuntu)编辑:如果您真的想使用sed
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
如何做到这一点,但是这个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
此外,如果你打算做更多批量重命名,考虑一下。这是一个非常好和强大的图形用户界面。而且,它是免费的
祝你好运实际上,可以这样做:
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
答案的原因是基本上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}
在普通sh
(以及[…]]
)中不可用,下面是一个仅使用sh
语法和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
这实际上是可行的。没有人知道如何使用
sed
;)我编辑添加了sed
解决方案-当我第一次回答时,我使用了perl
,因为sed
不是一个适合多行编辑的工具(正如你从一行中可以看到的,perl-one更容易理解)。嗯,我仍然喜欢Python而不是sed
。使用@Blender:sed的困难之处在于它将换行视为开始一个全新的输入行。我的sed
版本只是从输入中删除空行。@blender:谢谢你的脚本。我运行的很好,但是文件名仍然是跨多行的。是哪个角色造成的?。显然,\\r和\\n不是罪魁祸首:(你确定这不仅仅是换行符和空格吗?对我来说,长文件名沿着空格分开。如果你愿意,我可以修改它,用下划线替换空格。也许会有帮助?我也发布了一个空格替换脚本。测试一下,也许行得通?除了\n
和\r
原因之外,没有其他字符了。)换行符。可能只是您的文件管理器…您的意思是:?这只是Nautilus换行符。没有换行符,因此实际名称没有换行符。@blender:不,它们肯定不是空格,换行不是Nautilus造成的。当我检查文件属性时,文件名包含s一些奇怪的字符出现中断。如果我尝试将文件(它们是CSV文件)导入OpenOffice,文本导入的标题如下:“this%0Dis%the%0Dfullname.CSV”,其中%0D是导致文件名跨多行中断的字符。HTHBack为零;)我不知道为什么人们只是随机地否决投票。可能刚获得特权的新手想要得到那个新徽章…@Blender:谢谢。一个给你的徽章就要来了。它现在就像一种货币。我投票赞成,因为你总是提供高质量的答案。尽管我希望看到一些兼容的答案:)@Blender:也许我们可以创造一个地下经济,比如第二人生等等顺便说一句,我不承认我说过那样的话。