如何使用 awk 将引号从特定定界符添加到行尾?

How to add quotes from specific delimiter to end of the line, using awk?

我正在尝试修改文件:(file.txt)

abc~123~xyz~123456~12~0.12~14~1.1~  
omn~124~xdz~923231~13~0.0~13~1.1~14~0.45~19~80.1~

至 (new_file.txt)

abc~123~xyz~123456~"12~0.12~14~1.1~"  
omn~124~xdz~923231~"13~0.0~13~1.1~14~0.45~19~80.1~"

我尝试使用 awk 命令:

awk -F'~' '{for(i=1;i<=4;i++){printf "%s~", $i}; printf"\""} {for(i=5;i<=NF;i+=1){printf "%s~", $i}; printf "\"\n"}' file.txt > new_file.txt

但我得到的输出为:

abc~123~xyz~123456~"12~0.12~14~1.1~~"  
omn~124~xdz~923231~"13~0.0~13~1.1~14~0.45~19~80.1~~"

任何人都可以帮助我解决这个问题,因为我在每行末尾都有一个额外的“~”吗?任何参考资料也会有所帮助,因为我在处理 sed 和 awk 命令时感到困惑。

使用您显示的示例,请尝试执行以下 awk 程序。在 GNU awk 中编写和测试,应该在任何 awk.

中工作
awk -v s1="\"" '
match([=10=],/^[^~]*~([^~]*~){3}/){
  print substr([=10=],RSTART,RLENGTH) s1 substr([=10=],RSTART+RLENGTH) s1
}
' Input_file

解释: 简单的解释是,首先创建一个名为 s1awk 变量,它具有值作为其中的 ~。然后在主程序中使用 awkmatch 函数来匹配正则表达式 ^[^~]*~([^~]*~){3},它基本上匹配从值的开始到 ~ 的第 4 个值。一旦匹配,我将打印匹配的子字符串(从值的开始到 ~ 的第 4 次出现)然后打印 s1 和该行的其余值,然后是 s1(根据 OP 的要求)。



附加解决方案:假设你有不匹配~条件的行(意思不其中有 4 次 ~ 而你不想添加 ") 然后使用以下内容:

awk -v s1="\"" '
match([=11=],/^[^~]*~([^~]*~){3}/){
  [=11=]=substr([=11=],RSTART,RLENGTH) s1 substr([=11=],RSTART+RLENGTH) s1
}
1
' Input_file

您的行尾有一个 ~ 分隔符。因此,您在此字段分隔符之后有一个额外的空字段。您可以通过以下方式检查:

$ awk -F'~' '{print NF "|" $NF "|"}' file.txt
9||
13||

看到了吗?当打印最后一个空字段后跟 ~ 时,您只需将它连接到前一个空字段,即 ~~。尝试:

$ awk -F '~' -vOFS='~' '{ = "\"" ; $NF = $NF "\""; print}' file.txt
abc~123~xyz~123456~"12~0.12~14~1.1~"
omn~124~xdz~923231~"13~0.0~13~1.1~14~0.45~19~80.1~"

我们只是将~声明为输入和输出(带变量OFS)字段分隔符,在第5个字段前加一个",在最后一个字段后加1,然后打印。

这个 sed 将是相当简单的解决方案:

sed -E 's/^(([^~]*~){4})(.*)/""/' file

abc~123~xyz~123456~"12~0.12~14~1.1~"
omn~124~xdz~923231~"13~0.0~13~1.1~14~0.45~19~80.1~"

同样使用gnu awk

awk '{print gensub(/^(([^~]*~){4})(.*)/, "\1\"\3\"", "1")}' file

abc~123~xyz~123456~"12~0.12~14~1.1~"
omn~124~xdz~923231~"13~0.0~13~1.1~14~0.45~19~80.1~"

还有 GNU awk:

awk '{sub(/~$/,"~\"");print gensub(/~/, "~\"", 4)}' file
abc~123~xyz~123456~"12~0.12~14~1.1~"
omn~124~xdz~923231~"13~0.0~13~1.1~14~0.45~19~80.1~"
  • ~ 的两次替换为 ~",一次替换为 sub(),一次替换为第 4 次替换为 gensub()