Bash 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'`;

我运行了一个脚本,在一个目录中生成了大约10k个文件。我刚刚发现脚本中有一个bug,它导致一些文件名带有回车符(可能是'\n'字符)

我想运行sed命令从文件名中删除回车符

有人知道应该将哪些参数传递给sed,以便以所描述的方式清理文件名吗


我正在运行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:也许我们可以创造一个地下经济,比如第二人生等等顺便说一句,我不承认我说过那样的话。