如何使用 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
解释: 简单的解释是,首先创建一个名为 s1
的 awk
变量,它具有值作为其中的 ~
。然后在主程序中使用 awk
的 match
函数来匹配正则表达式 ^[^~]*~([^~]*~){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()
。
我正在尝试修改文件:(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
解释: 简单的解释是,首先创建一个名为 s1
的 awk
变量,它具有值作为其中的 ~
。然后在主程序中使用 awk
的 match
函数来匹配正则表达式 ^[^~]*~([^~]*~){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()
。