Awk 使用SED替换括号中的特定模式?
我对这个有点问题。。。 我试图使用Bash脚本(特别是Sed)来处理以下文本。当然,也欢迎使用其他方法!但我希望这是一个Bash解决方案 棘手的输入:Awk 使用SED替换括号中的特定模式?,awk,sed,grep,text-processing,Awk,Sed,Grep,Text Processing,我对这个有点问题。。。 我试图使用Bash脚本(特别是Sed)来处理以下文本。当然,也欢迎使用其他方法!但我希望这是一个Bash解决方案 棘手的输入: ("a"|"b"|"c")."A"|"B"|"C".("e"|"f")."E"|"F" 期望输出: ("a"|"b&
("a"|"b"|"c")."A"|"B"|"C".("e"|"f")."E"|"F"
期望输出:
("a"|"b"|"c")."ABC".("e"|"f")."EF"
主要是,我想我要做的是什么都不替换字符串“|”
,但将更改范围限制在括号中现有文本之外
问题变得更加疯狂,因为我有不同形式的文本输入和数据集。与中一样,带有括号和非括号的块(由
分隔)的组合也是不同的
提前谢谢
我用SED做了一些尝试:
gsed -E "s/(\.\"[[:graph:]]+)\"\|\"/\1/g" input.txt
我得到的结果是:
("a"|"b"|"c")."A"|"B"|"C".("e"|"f")."EF"
看起来我只获得了部分所需的输出…仅针对有限的范围…请尝试以下操作:
#!/bin/bash
awk 'BEGIN {FS = OFS = "."} # use "." as a field separator
{
for (i = 1; i <= NF; i++) { # loop over the fields
if ($i !~ "^\\(.+\\)$") { # if the fields is not enclosed with "(" and ")"
gsub("\"\\|\"", "", $i) # then remove "|"s
}
}
print
}' <<< '("a"|"b"|"c")."A"|"B"|"C".("e"|"f")."E"|"F"'
[解释]
块在处理输入之前只执行一次 文件初始化变量很有用BEGIN{}
- 当awk变量
被分配给“.”时, 输入行将自动 在“”上拆分。然后,FS
被分配给第一个字段$1
,(“a”|“b”|“c”)
分配给第二个$2
。。等等awk变量“A”|“B”|“C”
设置为字段数(本例中为4)NF
- for循环
for(i=1;i假设/理解:
- 字段由句点分隔
- 用帕伦包装的字段将被单独保留
- 所有其他字段都有前导/尾随双引号,而所有其他双引号以及管道都将被删除
一个$ cat pipes.dat ("a"|"b"|"c")."A"|"B"|"C".("e"|"f")."E"|"F" "j"|"K"|"L"."m"|"n"|"o"|"p".("x"|"y"|"z")
idea:awk
awk ' BEGIN { FS=OFS="." } # define input/output field separator as a period { printf "############\nbefore: %s\n",$0 # print a record separator and the current input line; # solely for display purposes; this line can # be removed/commented-out once logic is verified for (i=1; i<=NF; i++) # loop through fields if ( $i !~ "^[(].*[)]$" ) # if field does not start/end with parens then ... $i="\"" gensub(/"|\|/,"","g",$i) "\"" # replace field with a new double quote (+) modified string # whereby all double quotes and pipes are removed (+) # a new ending double quote printf "after : %s\n",$0 # print the newly modified line; # can be replaced with "print" once logic is verified } ' pipes.dat # read data from file; to read from a variable remove this line and ... #' <<< "${variable_name}" # uncomment this line
删除注释并进行
更改后:printf
awk ' BEGIN { FS=OFS="." } { for (i=1; i<=NF; i++) if ( $i !~ "^[(].*[)]$" ) $i="\"" gensub(/"|\|/,"","g",$i) "\"" print } ' pipes.dat
决定操作的顺序,它可能是可解的。括号是用来保护其中包含的内容,还是为什么不能折叠成“ABC”、“ABC”、“EF”?您好,不确定您所说的“为什么不能折叠成…”是什么意思。目的是防止替换
存在于parens中,同时对不在parens中的文本执行此操作。谢谢,这回答了我的问题:“括号是否保护了其中包含的内容?”。根据您看到的操作顺序制作一个表格,然后用笔和纸进行计算。如果无法进行计算,则尝试对其进行编程将有问题。为了便于讨论…字符组之间以句点(“|”
)分隔;是否所有奇数字段都用paren包装?偶数字段没有paren?您提到了
…请使用您尝试过的sed
命令和(错误)更新问题结果他们生成了带括号的字符组,这些字符可以出现在不同的地方,而不仅仅出现在奇数字段中……完全是可选的,以及“字段”的总数不是固定的。这很好。谢谢你的回答。我会对AWK做一些研究。虽然你可能会得到一个sed
解决方案来工作,但我想你会发现这些sed
解决方案会更容易理解(如果输入格式发生变化,也更容易修改)这是一个新手,所以也要考虑复习,好运气。谢谢你的回答。我会做一些关于AWK的研究。谢谢你的反馈。我增加了一些代码的解释,希望能帮助你学习。AWK
############ before: ("a"|"b"|"c")."A"|"B"|"C".("e"|"f")."E"|"F" after : ("a"|"b"|"c")."ABC".("e"|"f")."EF" ############ before: "j"|"K"|"L"."m"|"n"|"o"|"p".("x"|"y"|"z") after : "jKL"."mnop".("x"|"y"|"z")
awk ' BEGIN { FS=OFS="." } { for (i=1; i<=NF; i++) if ( $i !~ "^[(].*[)]$" ) $i="\"" gensub(/"|\|/,"","g",$i) "\"" print } ' pipes.dat
("a"|"b"|"c")."ABC".("e"|"f")."EF" "jKL"."mnop".("x"|"y"|"z")