我需要将文件中的\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
答案 0 :(得分:3)
您正试图替换十六进制字符串\x0D\x0A
,而该字符串只不过是CRLF
或\r\n
。
由于默认情况下awk会在LF
)上拆分其记录,因此您实际上不必尝试匹配您的\n
(或\x0a
)。因此,您要做的就是将\r
替换为,\r
(0x2c
是,
的十六进制值)。因此,这应该可以解决问题:
awk '(NR>1){sub("\r$",",\r"); print}' file
那您的脚本为什么会失败?
如前所述,awk适用于记录,默认记录分隔符为\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