在Unix中从文件中删除所有回车\r的最简单方法是什么?


当前回答

古老的学校:

tr -d '\r' < filewithcarriagereturns > filewithoutcarriagereturns

其他回答

如果你是一个Vi用户,你可以打开文件并删除回车符:

:%s/\r//g

或与

:1,$ s/^M//

请注意,您应该通过按ctrl-v和ctrl-m键入^M。

在任何UNIX®系统上删除\r:

这个问题中的大多数现有解决方案都是特定于gnu的,在OS X或BSD上不起作用;下面的解决方案可以在更多的UNIX系统上工作,也可以在从tcsh到sh的任何shell中工作,甚至还可以在GNU/Linux上工作。

在OS X、OpenBSD和NetBSD的tcsh上测试,在Debian GNU/Linux的bash上测试。


对话:

在OS X上的tcsh中,下面的sed代码片段可以与printf一起使用,因为sed和echo都不像GNU那样以特殊的方式处理\r:

sed `printf 's/\r$//g'` input > output

tr:

另一个选项是tr:

tr -d '\r' < input > output

sed和tr的区别:

看起来tr从输入文件中保留了一个尾随换行符,而在OS X和NetBSD(但在OpenBSD或GNU/Linux上没有)上的sed在文件的最后插入一个尾随换行符,即使输入在文件的最后缺少任何尾随\r或\n。


测试:

这里有一些测试示例,可以使用printf和hexdump -C来确保它在您的系统上工作;另外,如果你的系统缺少hexdump,也可以使用od -c:

% printf 'a\r\nb\r\nc' | hexdump -C
00000000  61 0d 0a 62 0d 0a 63                              |a..b..c|
00000007
% printf 'a\r\nb\r\nc' | ( sed `printf 's/\r$//g'` /dev/stdin > /dev/stdout ) | hexdump -C
00000000  61 0a 62 0a 63 0a                                 |a.b.c.|
00000006
% printf 'a\r\nb\r\nc' | ( tr -d '\r' < /dev/stdin > /dev/stdout ) | hexdump -C
00000000  61 0a 62 0a 63                                    |a.b.c|
00000005
% 

有一个名为dos2unix的实用程序存在于许多系统上,并且可以在大多数系统上轻松安装。

虽然这是一篇较老的文章,但最近我遇到了同样的问题。因为我有所有的文件重命名/tmp/blah_dir/,因为这个目录中的每个文件都有“/r”结尾字符(在文件末尾显示“?”),所以做脚本的方式是我唯一能想到的。

我想保存具有相同名称的最终文件(不拖尾任何字符)。 对于sed,问题是输出文件名,我需要提到其他东西(我不想要)。

我尝试了这里建议的其他选项(由于某些限制,不考虑dos2unix),但没有成功。

我尝试了“awk”,最后我使用“\r”作为分隔符,并采取了第一部分:

技巧是:

echo ${filename}|awk -F"\r" '{print $1}'

下面的脚本片段我用(我有所有文件有“\r”作为结尾字符在路径/tmp/blah_dir/)来解决我的问题:

cd /tmp/blah_dir/
for i in `ls`
  do
    mv   $i     $(echo $i | awk -F"\r" '{print $1}')
done

注:这个例子不是很精确,但接近我的工作(这里提到只是为了更好地了解我所做的工作)

对于UNIX……我注意到dos2unix从我的UTF-8文件中删除了Unicode头。在git bash (Windows)下,下面的脚本似乎工作得很好。它使用sed。注意,它只删除行尾的回车符,并保留Unicode标头。

#!/bin/bash

inOutFile="$1"
backupFile="${inOutFile}~"
mv --verbose "$inOutFile" "$backupFile"
sed -e 's/\015$//g' <"$backupFile" >"$inOutFile"