我有一个 csv 文件,其中有一些意外的换行符。该文件看起来或多或少像这样:
col1; col2; col3; col4
1a; 1b; 1c; 1d
2a; 2b; 2c
;2d # this should be in the row above
3a; 3b; 3c; 3d
我想将以 开头的每一行;
与之前的行连接起来,然后将其删除。我怎样才能做到这一点?
答案1
$ sed -e '
:loop
$!N
s/\n;/;/
tloop
P;D
' file.csv
随时在模式空间中保留 rwo 行。如果在下一行的开头看到分号,请截掉换行符并循环返回以将下一行读入模式空间。
当下一行没有分号时,退出循环,打印到第一个换行符,删除该部分并返回并将下一行附加到模式空间。
答案2
怎么样awk:
awk -F ';' '{while (NF < 4) {getline nextline; $0 = $0 nextline}} 1' file
答案3
以下sed
脚本可能正是您所需要的:
sed -n '$p;N;s/[[:blank:]]*\n[[:blank:]]*;/;/;P;D' csv_file
分解解释:
$p; # at last line of stream, just print it
N; # append the next line from input so that we always consider two lines at a time ...
s/[[:blank:]]*\n[[:blank:]]*;/;/; # then replace `\n;` (and any leading and trailing blanks) with just `;`, and ...
P; # print only the _first_ of the two lines present in memory and ...
D # then delete it and read one new line if memory becomes empty
请注意,第一个命令$p
实际上仅在输入行总数为奇数时才打印某些内容,因为脚本的其余部分确保内存中始终有来自输入流的两行