243

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

4

21 回答 21

285

我将假设您的意思是在行尾的回车(,CR , "\r"0x0d,而不是盲目地在文件中(据我所知,您可能将它们放在字符串的中间)。仅在第一行末尾使用此测试文件:CR

$ cat infile
hello
goodbye

$ cat infile | od -c
0000000   h   e   l   l   o  \r  \n   g   o   o   d   b   y   e  \n
0000017

dos2unix如果它已安装在您的系统上,这是要走的路:

$ cat infile | dos2unix -U | od -c
0000000   h   e   l   l   o  \n   g   o   o   d   b   y   e  \n
0000016

如果由于某种原因dos2unix您无法使用,那么sed将这样做:

$ cat infile | sed 's/\r$//' | od -c
0000000   h   e   l   l   o  \n   g   o   o   d   b   y   e  \n
0000016

如果由于某种原因sed您无法使用,那么ed将以一种复杂的方式进行操作:

$ echo ',s/\r\n/\n/
> w !cat
> Q' | ed infile 2>/dev/null | od -c
0000000   h   e   l   l   o  \n   g   o   o   d   b   y   e  \n
0000016

如果您的盒子上没有安装任何这些工具,那么您遇到的问题比尝试转换文件要大:-)

于 2009-04-29T02:25:10.420 回答
259
tr -d '\r' < infile > outfile

tr(1)

于 2009-04-29T13:48:10.200 回答
46

在我看来,Linux 上最简单的方法是,

sed -i.bak 's/\r$//g' <filename>

-i将就地编辑文件,而.bak将通过制作文件副本并在末尾添加扩展名.bak来创建原始文件的备份。(您可以在 之后指定您想要的任何内容-i,或仅指定-i不创建备份。)

替换运算符周围的强引号's/\r//'必不可少的。没有它们,shell 将解释\r为 escape+r 并将其简化为 plain r,并删除所有小写字母r。这就是Rob在 2009 年上面给出的答案不起作用的原因。

添加/g修饰符可确保\r删除多个,而不仅仅是第一个。

于 2017-01-04T10:47:21.560 回答
40

老套:

tr -d '\r' < filewithcarriagereturns > filewithoutcarriagereturns
于 2009-04-29T13:50:27.030 回答
29

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

于 2009-04-28T22:10:32.950 回答
8

sed -i s/\r// <filename>或类似的东西;请参阅man sed或在网络上提供有关使用sed.

需要指出的一点是上面“回车”的确切含义;如果您真正的意思是单个控制字符“回车”,那么上面的模式是正确的。如果您的意思是,更一般地说,CRLF(回车和换行,这是在 Windows 下实现换行的方式),那么您可能想要替换\r\n。Linux/Unix 中的裸换行符(换行符)是\n.

于 2009-04-28T22:12:37.813 回答
7

如果您是 Vi 用户,您可以使用以下命令打开文件并删除回车:

:%s/\r//g

或与

:1,$ s/^M//

请注意,您应该通过按 ctrl-v 然后按 ctrl-m 来输入 ^M。

于 2012-09-05T11:13:53.417 回答
6

又是一个解决方案……因为总会有一个解决方案:

perl -i -pe 's/\r//' filename

这很好,因为它已经到位并且适用于我使用过的各种 unix/linux。

于 2016-01-28T15:09:42.847 回答
5

其他人推荐dos2unix,我也强烈推荐。我只是提供更多细节。

如果已安装,请跳至下一步。如果尚未安装,我建议通过以下方式安装它yum

yum install dos2unix

然后你可以像这样使用它:

dos2unix fileIWantToRemoveWindowsReturnsFrom.txt
于 2015-07-23T15:25:03.203 回答
4

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

这个问题中的大多数现有解决方案都是特定于 GNU 的,并且不适用于 OS X 或 BSD;下面的解决方案应该可以在更多的 UNIX 系统上工作,并且在任何 shell 中,从tcshto sh,但即使在 GNU/Linux 上也仍然可以工作。

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


sed

tcshOS X 上,以下sed代码段可以与 一起使用printf,因为它既不sed也不会像 GNU 那样以特殊方式echo处理:\r

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

tr

另一种选择是tr

tr -d '\r' < input > output

sed和之间的区别tr

似乎tr保留了输入文件中缺少尾随换行符的情况,而sed在 OS X 和 NetBSD(但不是在 OpenBSD 或 GNU/Linux 上)即使输入缺少任何内容,也会在文件的最后插入尾随换行符在文件的末尾\r\n末尾。


测试:

以下是一些示例测试,可用于确保它在您的系统上运行,使用printfand hexdump -C; 或者,od -c如果您的系统丢失,也可以使用hexdump

% 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
% 
于 2019-08-23T22:36:03.810 回答
3

如果您使用的操作系统(如 OS X)没有该dos2unix命令但有 Python 解释器(版本 2.5+),则此命令等效于以下dos2unix命令:

python -c "import sys; import fileinput; sys.stdout.writelines(line.replace('\r', '\n') for line in fileinput.input(mode='rU'))"

这处理命令行上的命名文件以及管道和重定向,就像dos2unix. 如果将此行添加到 ~/.bashrc 文件(或其他 shell 的等效配置文件):

alias dos2unix="python -c \"import sys; import fileinput; sys.stdout.writelines(line.replace('\r', '\n') for line in fileinput.input(mode='rU'))\""

...下次您登录(或source ~/.bashrc在当前会话中运行)时,您将能够以dos2unix与其他示例相同的方式在命令行上使用该名称。

于 2012-11-28T18:16:43.983 回答
2

你可以简单地这样做:

$ echo $(cat input) > output
于 2015-04-21T12:58:51.383 回答
2

事情是这样的,

%0d是回车符。使其与 Unix 兼容。我们需要使用下面的命令。

dos2unix fileName.extension fileName.extension

于 2015-12-17T20:18:41.210 回答
1

试试这个将dos文件转换成unix文件:

从dos文件

于 2010-07-20T09:50:41.280 回答
1

对于 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"
于 2017-06-29T20:24:53.053 回答
1

如果您正在运行 X 环境并拥有适当的编辑器(Visual Studio 代码),那么我将遵循建议:

Visual Studio Code:如何显示行尾

只需转到屏幕的右下角,Visual Studio 代码就会向您显示文件编码和文件后跟的行尾约定,只需单击一下即可切换。

只需在 linux 环境中使用可视代码作为 notepad++ 的替代品,您就可以开始使用了。

于 2017-08-18T09:00:54.847 回答
1

cat input.csv | sed 's/\r/\n/g' > output.csv

为我工作

于 2020-09-24T15:38:16.127 回答
1

使用sed

sed $'s/\r//' infile > outfile

sed在 Windows 版 Git Bash 上使用

sed '' infile > outfile

第一个版本使用ANSI-C 引用\,如果命令从脚本运行,可能需要转义。第二个版本利用了通过删除和字符sed逐行读取输入文件的事实。但是,在将行写入输出文件时,它只附加一个字符。只需修改即可设计出更通用和跨平台的解决方案\r\n\nIFS

IFS=$'\r\n' # or IFS+=$'\r' if the lines do not contain whitespace
printf "%s\n" $(cat infile) > outfile
IFS=$' \t\n' # not necessary if IFS+=$'\r' is used

警告:此解决方案执行文件名扩展(如果设置了*,?[...]更多)。extglob仅当您确定文件不包含特殊字符或您想要扩展时才使用它。
警告:没有一个解决方案可以\在输入文件中处理。

于 2020-10-27T15:47:45.820 回答
0

我用过python,这里是我的代码;

end1='/home/.../file1.txt'
end2='/home/.../file2.txt'
with open(end1, "rb") as inf:
     with open(end2, "w") as fixed:
        for line in inf:
            line = line.replace("\n", "")
            line = line.replace("\r", "")
            fixed.write(line)
于 2016-03-10T01:15:28.743 回答
0

虽然这是一个较旧的帖子,但最近我遇到了同样的问题。由于我在 /tmp/blah_dir/ 中要重命名所有文件,因为该目录中的每个文件都有“/r”尾随字符(在文件末尾显示“?”),所以只有我能想到的脚本方式。

我想用相同的名称保存最终文件(不带任何字符)。使用 sed,问题是输出文件名,我需要提及其他内容(我不想要)。

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

我最终尝试了“awk”,它在我使用“\r”作为分隔符并采用第一部分的情况下工作

诀窍是:

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

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

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

注意:这个例子虽然与我的工作很接近,但并不是很准确(在这里提及只是为了更好地了解我所做的事情)

于 2019-02-18T14:49:47.717 回答
0

我制作了这个 shell 脚本来删除 \r 字符。它适用于 solaris 和 red-hat:

#!/bin/ksh

LOCALPATH=/Any_PATH

for File in `ls ${LOCALPATH}`
do
   ARCACT=${LOCALPATH}/${File}
   od -bc ${ARCACT}|sed -n 'p;n'|sed 's/015/012/g'|awk '{$1=""; print $0}'|sed 's/ /\\/g'|awk '{printf $0;}'>${ARCACT}.TMP
   printf "`cat ${ARCACT}.TMP`"|sed '/^$/d'>${ARCACT}
   rm ${ARCACT}.TMP
done

exit 0
于 2019-11-27T15:00:02.570 回答