我正在尝试使用管道分隔符 ( |
) grep 第 4 列并替换其中的所有双引号,然后再次用双引号将该字符串引起来。
样本文件:
col1|col2|col3|col4|col5|col6|col7|col8|col9
value1|value2|value3|"|||||value"4|value5|value6|"||value"7|value8|value9
问题是第 4 列是用户可以写入任何内容的地方,甚至是管道,这是我的分隔符,它破坏了我的进程。
例如第 4 列可能是
"|||||value"4
现在我正在尝试编写转到第 4 列的命令,替换所有双引号,然后再次用双引号将其括起来,以便我可以将其视为单个字符串以使我的流程正常工作。
第 4 列所需的输出为
"|||||value4"
同样,我对第 7 列做了同样的事情,第 7 列所需的输出是
"||value7"
最终输出应如下所示:
col1|col2|col3|col4|col5|col6|col7|col8|col9
value1|value2|value3|"|||||value4"|value5|value6|"||value7"|value8|value9
请建议。
答案1
使用csvkit
:
$ csvformat -d '|' -D '|' file.csv
col1|col2|col3|col4|col5
test|test_f|21/03/2017|"|||||USER RIGHTa anything here"|123
-d
和标志-D
分别定义输入和输出中使用的分隔符。
答案2
和sed
假设您只有 5 列,并且在您的情况下应引用的列是第 4 列:
sed -E 's/"//g; s/^(([^|]*\|){3})(.*)(\|[^|]*)$/\1"\3"\4/' infile
即使用户没有输入引号,如果用户或管道输入了任何引号,这也将起作用。
这是一个awk
解决方案也按要求:
$ awk -F'|' '{ for (i=1; i<NF; i++){if (i>3)gsub("\"","");
printf (i!=(NF-1))?$i"|"((i==3)?"\"":""):$i"\"|"}; print $NF}' infile
col1|col2|col3|"col4"|col5
test|test_f|21/03/2017|"|||||USER RIGHTa anything here"|123