我正在根据下面提供的示例寻找下面的输入
样品
eno~ename~address~zip
123~abc~~560000~"a~b~c"
245~"abc ~ def"~hyd~560102
333~"ghi~jkl"~pub~560103
444~ramdev "abc def"~ram~10000
预期产量
"eno"~"ename"~"address"~"zip"
"123"~"abc"~""~"560000"~"a~b~c"
"245"~"abc ~ def"~"hyd"~"560102"
"333"~"ghi~jkl"~"pub"~"560103"
"444"~"ramdev ""abc def"""~"ram"~"10000"
当前代码:
awk 'BEGIN{s1="\"";FS=OFS="~"} {for(i=1;i<=NF;i++){if($i!~/^\"|\"$/){$i=s1 $i s1}}} 1' sample
当前代码不适用于最后一行。这是对insert quotes for each field using awk
的增强答案 0 :(得分:2)
这可能对您有用(GNU sed):
cat <<\! | sed -Ef - file
:a;s/^([^"~][^~]*~+("[^~"]*"~+[^"~][^~]*~+)*[^"]*"[^"~]*)~/\1\n/;ta; #1
s/.*/~&/ #2
s/~"([^"]*)"/~\1/g #3
s/"/""/g #4
s/.// #5
s/[^~]*/"&"/g #6
y/\n/~/; #7
!
此sed脚本的工作方式如下:
~
可以与字段定界符混淆。它们需要替换为当前行中不存在的唯一字符。由于sed使用换行符来分隔其输入,因此换行符无法在模式空间中显示,因此是此类字符的理想选择。字段由三种类型的字符串组成:
a)不以双引号开头和结尾且没有引号的字符串。
b)用双引号引起来的字符串
c)不以双引号开头和结尾并且在其中用引号引起来的字符串。
后面的字符串需要其中包含任何~
才能替换\n
。这可以通过以下方式实现:遍历当前行,留下类型a,b或c的字段,这些字段不包含~
,而仅替换后面字符串中的~
。
为便于下一步操作,我们为第一个字符串引入了字段定界符。
删除所有包含双引号的字段(请参见1b)。
所有剩余的双引号都在类型1c的字符串中,并且可以通过在前缀"
前面加引号。
现在删除步骤2中引入的初始字段定界符。
用双引号将所有字段引起来。
用其原始值~
替换在步骤1中引入的换行符。
看来,GNU sed有一个错误,即如果翻译命令(y /../../)是脚本中的最后一个命令或一行命令,则需要在其后缀;
。>
以上解决方案可以输入一长行:
sed -E ':a;s/^([^"~][^~]*~+("[^~"]*"~+[^"~][^~]*~+)*[^"]*"[^"~]*)~/\1\n/;ta;s/.*/~&/;s/~"([^"]*)"/~\1/g;s/"/""/g;s/.//;s/[^~]*/"&"/g;y/\n/~/;' file