从文件的每一行中删除第一个 ^M

从文件的每一行中删除第一个 ^M

数据从第二行开始。 是否有一个简单的脚本或实用程序来删除第一个实例^m 每行数据?

这个问题也可以改写为:如何^m删除每个第二个(偶数)实例?期待有趣(聪明)的回应。最好是在 Ubuntu 或类似系统中。

在此输入图像描述

原始数据可供巧妙剪切、粘贴和解析:

Date,From,To,Flight_Number,Airline,Distance,Duration,Seat,Seat_Type,Class,Reason,Plane,Registration,Trip,Note,From_OID,To_OID,Airline_OID,Plane_OID^M
- -,JFK,OTBD,American Airlines (AA),American Airlines,6687,13:52,,,,,777^M,,,"Direct",3797,2241,24^M
- -,JFK,OTBD,Qatar Airways (QR),Qatar Airways,6687,13:52,,,,,77W^M,,,"Direct",3797,2241,4091^M

话虽这么说,提出这个问题的原因是意外的 ^m 导致了 Libre-Office Calc(电子表格)的导入问题:它导致了预期的换行。

在此输入图像描述

答案1

假设您想将文件保留为 DOS 格式(CRLF 行结尾),我们可以作弊;消除全部CR,然后将它们添加回行尾。

所以

tr -d '\015' < srcfile | unix2dos > newfile

编辑详细描述:

tr -d '\015'

将剥离全部文件中的 control-M 字符。 -dtotr表示“删除”,'\015'是八进制格式的 control-M 字符。

unix2dos

通过在 LF 字符之前插入 CR (control-M),将任何 LF(换行;control-J;)字符转换为 CRLF;这会将 unix 格式的文本文件转换为 DOS 格式的文本文件。

将两者放在一起,我们删除所有流氓 ^M,并确保唯一的 ^M 位于每行的末尾。

答案2

(基于您的图像显示^M为蓝色,而不是正常的白色这一事实,我假设您指的是回车符(CR)字符,而不是字面插入符+M组合。(是的,这是发布的情况文本作为图像实际上很有帮助。))

1) 由于您将数据提供给 LibreOffice,您可以看看它是否可以很好地处理 Unix 风格的换行符(只是 LF,而不是 CRLF),并且完全删除所有回车符:

tr -d '\r' < input > output

2) 如果你想保留 DOS 风格的 CRLF 行结尾,并且只删除行中间的 CR:s(即后面不紧跟着 LF),你可以在 Perl 中执行以下操作:

perl -pe 's/\r(?!\n)//g' < input > output

s/xxx/yyy/g替换所有出现的xxxwith yyy\r被解释为回车符,(?!\n)表示“后面不跟\n”,其中\n是换行符/换行符。替换为空,因此匹配项被删除。

您可以使用 执行类似的操作sed,但\r并非所有版本的 都支持转义sed,并且ctrl-M在命令行上逐字输入字符有点烦人。 (Ubuntu 将有 GNU sed,它支持它,但它也有 Perl,所以。)

我特别忽略了您所说的关于每行第一次出现以及忽略第一行的所有内容,因为我发现信任输入始终包含正确数量的虚假额外控制字符有点脆弱。 (如果某行碰巧有两个^M:s,或者没有?)

答案3

这是使用的一种选择sed

sed -i.bak '2,$s/\r//' filename

它能做什么:

  1. -i.bak将原始文件的备份添加为filename.bak.
  2. 2,$是从第二行开始并继续到文件末尾。
  3. s/\r//删除每行中第一次出现的回车符(屏幕截图中的^M)。

使用发布的摘录的示例命令,我在 vi 中手动输入了回车符:

$ cat -A test_sed
Date,From,To,Flight_Number,Airline,Distance,Duration,Seat,Seat_Type,Class,Reason,Plane,Registration,Trip,Note,From_OID,To_OID,Airline_OID,Plane_OID^M$
- -,JFK,OTBD,American Airlines (AA),American Airlines,6687,13:52,,,,,777^M,,,"Direct",3797,2241,24^M$
- -,JFK,OTBD,Qatar Airways (QR),Qatar Airways,6687,13:52,,,,,77W^M,,,"Direct",3797,2241,4091^M$

$ sed -i.bak '2,$s/\r//' test_sed

$ cat -A test_sed
Date,From,To,Flight_Number,Airline,Distance,Duration,Seat,Seat_Type,Class,Reason,Plane,Registration,Trip,Note,From_OID,To_OID,Airline_OID,Plane_OID^M$
- -,JFK,OTBD,American Airlines (AA),American Airlines,6687,13:52,,,,,777,,,"Direct",3797,2241,24^M$
- -,JFK,OTBD,Qatar Airways (QR),Qatar Airways,6687,13:52,,,,,77W,,,"Direct",3797,2241,4091^M$

答案4

回答主题中的问题:删除文件中所有其他 CR 字符,与 GNU awk

awk -v RS='\r' '{ORS = NR % 2 ? RT : ""; print}' < infile > outfile

它将(输入)记录分隔符设置为 CR,并将输出记录分隔符设置为 RT(该记录的记录终止符可以是 CR,如果它是最后一条记录并且输入不以 CR 字符结尾,则可以为空)对于偶数记录(当NR % 2 != 0)。

相关内容