0

我刚刚将几个文件从 Windows 复制到了 unix,它们最后都有^M。我知道如何使用 vi 删除它们,但我一次只能做一个文件,有没有办法可以为文件夹中的所有文件做到这一点?大约有 60 个文件,手动为所有文件执行此操作非常耗时!

我也愿意使用其他工具!

PS:操作系统是 Solaris

谢谢

4

3 回答 3

2

为了后代,让我们从 VI 中发布解决方案。您可以像这样删除每行末尾的Ctrl- :M

:%s/^V^M$//

请注意,这是您输入的内容,wnere 的^V意思是Ctrl-V^M意思是Ctrl- M。这里的想法是^V将“转义”以下 ^M,以便您可以在替换正则表达式中匹配它。

%表达式的意思是“在每一行都这样做”。

请注意,这在 vim 中可能有效,也可能无效,具体取决于您的设置。

但是您的问题询问如何在 vi 中执行此操作,在 vi 中您无法轻松更改多个文件。如果您愿意使用其他工具,请在您的问题中说明。

您可以在单个文件或流上使用 sed:

$ printf 'one\r\ntwo\r\n' > /tmp/test.txt
$ od -c < /tmp/test.txt
0000000    o   n   e  \r  \n   t   w   o  \r  \n                        
0000012
$ sed -i'' -e 's/^M$//' /tmp/test.txt 
$ od -c < /tmp/test.txt
0000000    o   n   e  \n   t   w   o  \n                                
0000010
$ 

在这种情况下,在 FreeBSD 的 /bin/sh 中,我转义了^Mby ... 你猜对了 ... using ^V.

使用 sed 的-i选项时,您可以指定多个文件,它们都将被原地修改,也许无需将其包装在脚本中。如果您无论如何都想将其放入脚本中,我建议您尝试这样做,如果它不起作用,然后寻求帮助。这就是 StackOverflow 方式。:-)

或者只是使用 Jonathan 的 for 循环示例。您不需要临时文件。

更新

如果您sed没有-i选项,那么您仍然可以在 for 循环中轻松完成此操作:

[ghoti@pc ~]$ od -c /tmp/test1.txt
0000000    o   n   e  \r  \n   t   w   o  \r  \n                        
0000012
[ghoti@pc ~]$ for f in /tmp/test*.txt; do sed -e 's/^M$//' "$f" > /tmp/temp.$$ && mv -v /tmp/temp.$$ "$f"; done
/tmp/temp.26687 -> /tmp/test1.txt
/tmp/temp.26687 -> /tmp/test2.txt
[ghoti@pc ~]$ od -c /tmp/test1.txt
0000000    o   n   e  \n   t   w   o  \n                                
0000010
于 2013-11-08T17:24:50.130 回答
1

如果你的机器上没有dos2unixordtou命令,你可以使用tr

for file in "$@" # LIst of files passed as argument to script
do
    tr -d '\015' < "$file" > tmp.$$
    cp tmp.$$ "$file"
done
rm tmp.$$

如果您中断,您可以添加trap命令进行清理。使用cp而不是mv保留所有者、权限、符号链接、硬链接。

于 2013-11-08T16:57:47.670 回答
0

使用命令dos2ux

dos2ux file >file2
于 2013-11-11T10:15:42.760 回答