需要在文件中将\ x0d \ x0a替换为\ x2c \ x0d \ x0a

时间:2018-10-23 16:09:54

标签: awk hex

我需要将文件中的\x0d\x0a替换为\x2c\x0d\x0a

以下内容不做任何事情:

awk '{if NR> 1 {gsub(/\x0D\x0A/,"\x2C\x0D\x0A"); print}}' test.csv > testfixed.csv
$ xxd test.csv
00000e0: 350d 0a45 4941 2d39 3330 2c44 6169 6c79  5..EIA-930,Daily
00000f0: 2c4e 5949 532c 2c55 5443 302c 3030 3132  ,NYIS,,UTC0,0012

2 个答案:

答案 0 :(得分:3)

您正试图替换十六进制字符串\x0D\x0A,而该字符串只不过是CRLF\r\n

由于默认情况下会在字符(即LF)上拆分其记录,因此您实际上不必尝试匹配您的字符\n(或\x0a)。因此,您要做的就是将\r替换为,\r0x2c,的十六进制值)。因此,这应该可以解决问题:

awk '(NR>1){sub("\r$",",\r"); print}' file

那您的脚本为什么会失败?

如前所述,适用于记录,默认记录分隔符为字符。这意味着字符(也写为\n并且具有十六进制值\x0a)决不会成为记录$0的一部分。同样,print语句在记录之后自动添加其记录输出分隔符ORS。默认情况下,它还是字符。因此,您不必尝试替代它。您所要做的就是:

awk 'NR > 1 {sub(/\x0D$/,"\x2C\x0D"); print}' test.csv > testfixed.csv

那么可以用其十六进制值代替吗?

是的,显然是这样!

echo -n "Hello World" | awk 'sub(/\x57\x6f\x72\x6c\x64/,"\x43\x6f\x77")'

但是如何更改

您可以重新定义输出记录分隔符ORS

awk -v ORS="whatever" '1'

此外,使用GNU awk,您可以关注glenn jackman's solution


非常相关:Why does my tool output overwrite itself and how do I fix it?

答案 1 :(得分:1)

换行符\n\x0A不会出现在每个记录中,因为默认情况下它是记录分隔符。

我会这样做:将 input output 记录分隔符定义为\r\n,然后对于行号> 1,在记录中附加一个逗号:

$ printf "a\r\nb\r\nc\r\n" >| file

$ hexdump -C file
00000000  61 0d 0a 62 0d 0a 63 0d  0a                       |a..b..c..|
00000009

$ awk 'BEGIN {RS = ORS = "\r\n"} NR > 1 {$0 = $0 ","} 1' file | hexdump -C
00000000  61 0d 0a 62 2c 0d 0a 63  2c 0d 0a                 |a..b,..c,..|
0000000b