试图用另一个模式替换模式

时间:2015-01-11 23:54:00

标签: linux bash awk

这是我在这个网站上的第一个问题。(很高兴我发现了这个社区)

我正在尝试替换文件中的特定模式(多行)看起来像这样:

Bla bla bla bla |SMTH AWESOME INSIDE >>> LOL| bla bla bla | let's do it again >>> AWESOME |

进入看起来像这样的格式

Bla bla bla bla ( LOL | SMTH AWESOME INSIDE ) bla bla bla ( AWESOME | let's do it again )

我尝试使用一个逐字解析行的代码,如果找到" |"字符开始创建包含第一个单词的字符串,然后在找到>>>之后字符它开始创建第二个字符串,直到找到" |"最后一个角色,但它没有用。

之后我也尝试使用AWK(但由于我是linux新手,我也失败了。

awk -F 'BEGIN { FS=OFS="|" } { sub(/.*<<</,"", $2); }1' $1 }'    

然后用sed解析输出(删除)和(两个字符串中的字符。但它没有工作。

感谢您的阅读。

4 个答案:

答案 0 :(得分:2)

看起来这只是每行中的一个简单替换,所以你需要的只是sed:

$ sed 's/| *\([^|]*\) >>> \([^|]*\) *|/( \2 | \1 )/g' file
Bla bla bla bla ( LOL | SMTH AWESOME INSIDE ) bla bla bla ( AWESOME  | let's do it again )

您可以在GNU awk中使用gensub()或其他具有match()和substr()的awks执行相同的操作。

答案 1 :(得分:1)

Perl的正则表达式具有“非贪婪”匹配功能,而awk则没有:

perl -pe '
    s/ \|       # the first delimiter
       (.*?)    # capture up to ...
       >>>      # the middle delimiter
       (.*?)    # capture up to ...
       \|       # the last delimiter
    /($2 | $1)/gx
' file
Bla bla bla bla ( LOL | SMTH AWESOME INSIDE ) bla bla bla ( AWESOME  |  let's do it again )

答案 2 :(得分:1)

sed 中使用扩展的正则表达式:

sed -r 's/\|([^|]+)[[:space:]]*>>>[[:space:]]*([^|]+)\|/( \2 | \1 )/g' File

<强>逻辑:

我们会寻找一种模式,该模式以|开头,后跟一系列非|字符,后跟>>>,后跟一系列非|字符。查看使用()完成的分组。然后我们根据需要替换这些模式。 ( \2 | \1 )是替换模式,其中\ 1和\ 2分别是第一个和第二个分组。

使用 sed 中的基本正则表达式:

sed 's/|\([^|]*\)[[:space:]]*>>>[[:space:]]*\([^|]*\)|/( \2 | \1 )/g' File

答案 3 :(得分:0)

让我们试试

awk 'NR%2{ printf("%s", $0) } NR%2==0{ printf("( %s %s",$NF,RS); gsub(/>>>.*$/,")"); printf("%s",$0) }' RS='|' file
Bla bla bla bla ( LOL | SMTH AWESOME INSIDE ) bla bla bla ( AWESOME | let's do it again )

RS|定义为记录分隔符。因此,当输入记录号(NR)不是2的模块(NR%2返回1)时,则打印该记录本身。如果NR是2的模块(NR%2==0表示如果记录是2的模块),则打印一个打开的括号,然后从中打印最后一个字段并打印记录分隔符(printf("( %s %s",$NF,RS)) ,然后用小括号替换>>>.*$并打印剩下的记录(gsub(/>>>.*$/,")"); printf("%s",$0)