ChatGPT解决这个技术问题 Extra ChatGPT

在 Unix 中删除回车

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

你是在谈论'\r''\n',还是只是讨厌的'\r's?
我认为使用 tr -d 命令是最简单的方法,但我想知道如何仅删除 最后一个回车符

p
paxdiablo

我将假设您的意思是回车(CR, "\r", 0x0d)在行的ends,而不是盲目地在文件中(您可以据我所知,将它们放在字符串中间)。仅在第一行末尾使用带有 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

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


\r 仅适用于 GNU sed,否则您可以这样做:sed `echo "s/\r//"`
sedecho 在 MacO 上都不能识别 \r。在这种情况下,只有 printf "\r" 似乎有效。
要详细说明 @steve 的评论:在 Mac 上,使用以下命令:sed "s/$(printf '\r')\$//"
要解决 Mac 上的问题,您还可以在单引号 sed 字符串前面加上 $,如下所示:sed $'s@\r@@g' |od -c(但如果您要替换为 \n,则需要对其进行转义)
我不能 100% 确定,但对于 OS X,使用 CTRL-V + CTRL-M 代替 \r 看起来可能会起作用。
H
Henrik Gustafsson
tr -d '\r' < infile > outfile

请参阅tr(1)


不太好:1. 不能就地工作,2. 可以替换 \r 也不能在 EOL (这可能是也可能不是你想要的......)。
1. 大多数 unixy 工具都是这样工作的,这通常是最安全的处理方式,因为如果你搞砸了,你仍然拥有原始工具。 2.所述问题是删除回车,而不是转换行尾。但是还有很多其他答案可能会更好地为您服务。
如果您的 tr 不支持 \r 转义,请尝试 '\015' 或文字 '^M'(在许多终端上的许多 shell 中,ctrl-V ctrl-M 将产生文字 ctrl-M 字符)。
那么当你想要 outfile = infile 时如何改变它呢?
@donlan,回复较晚,但您通常使用以下内容:someProg <in >out && mv out in
e
ecm

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

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

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

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

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


我建议不要使用 -i 标志,因为它会修改原始文件,如果您希望保持不变,可能会很危险
不要只使用 -i 而是 -i.bak 它将创建带有 .bak 扩展名的原始文件的备份
p
plinth

老套:

tr -d '\r' < filewithcarriagereturns > filewithoutcarriagereturns

E
Emil H

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


有时它也被称为 fromdos(和 todos)。
链接现已关闭,请改为访问 http://dos2unix.sourceforge.net/
R
Rob

sed -i s/\r// <filename> 或类似的东西;请参阅 man sed 或网络上有关使用 sed 的大量信息。

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


我正在尝试使用 --> sed 's/\r\n/=/' countryNew.txt > demo.txt 这不起作用。 “老虎”“狮子”。
我们是否认为这意味着你在 Mac 上?我注意到 Darwin sed 默认情况下似乎具有与大多数 Linux 版本不同的命令和功能集......
仅供参考,s/\r// 似乎没有删除 OS X 上的回车符,它似乎删除了文字 r 字符。我不确定为什么会这样。也许它与引用字符串的方式有关?作为一种解决方法,使用 CTRL-V + CTRL-M 代替 \r 似乎可行。
A
Alex Giotis

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

:%s/\r//g

或与

:1,$ s/^M//

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


不太好:如果文件的每一行都有 CR(即是一个正确的 DOS 文件),vim 将使用 filetype=dos 加载它,并且根本不显示 ^M-s。解决这个问题需要大量的击键,这不是 vim 的用途;)。我只选择 sed -i,然后使用 `-e 's/\r$//g' 将删除限制为 EOL 时的 CR。
J
James Oravec

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

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

yum install dos2unix

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

dos2unix fileIWantToRemoveWindowsReturnsFrom.txt

C
Chris G

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

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

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


如果您想要备份原始文件,建议使用 -i.bak
c
cnst

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

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

tcsh 中的 OS X、OpenBSD 和 NetBSD 以及 bash 中的 Debian GNU/Linux 上进行了测试。

使用 sed:

在 OS X 上的 tcsh 中,以下 sed 片段可以与 printf 一起使用,因为 sedecho 都不像 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

测试:

下面是一些使用 printfhexdump -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
% 

C
Chris Johnson

如果您使用的操作系统(如 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 名称。


m
mma7

你可以简单地这样做:

$ echo $(cat input) > output

不知道为什么有人给'-1'。这是一个非常好的答案(也是唯一对我有用的答案)。
哦,对不起,是我。等等,你看,它对 '\r' 真的不起作用!
@FractalSpace 这是一个糟糕的主意!它完全破坏了文件中的所有间距,并使文件的所有内容都由 shell 解释。尝试使用包含一行 a * b 的文件...
S
Sireesh Yarlagadda

事情是这样的,

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

dos2unix fileName.extension fileName.extension


h
hawston

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

从dos文件


L
LexH

对于 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"

9
99Sono

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

Visual Studio Code: How to show line endings

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

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


或者,在将文件复制到 Linux 系统之前,在 Windows 系统上使用 Notepad++ 的命令 Edit / EOL Conversion / Unix (LF)
B
Burak Gök

使用 sed

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

在 Windows 版 Git Bash 上使用 sed

sed '' infile > outfile

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

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,则为 *?[...] 等)。仅当您确定文件不包含特殊字符或您想要扩展时才使用它。
警告:没有任何解决方案可以处理输入文件中的 \


N
Nicolas Pepinster

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

为我工作


R
Raphael

我用过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)

A
Ashish K Srivastava

虽然这是一个较旧的帖子,但最近我遇到了同样的问题。由于我在 /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

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


H
Heloderma Suspectum

我制作了这个 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