包含经过编辑的字符串的重复行

包含经过编辑的字符串的重复行

我需要找到一种方法来复制包含小编辑字符串的文件中的行。受骗者必须出现在原始行上方。会是我最好的选择sed吗?awk

理想情况下,在新行中替换puppies为,并替换为。bunniesIYou

例如:

  • 输入文件:
    I have puppies cute 
    I have two kitties
    I have three puppies cute
    I have four kitties
    
  • 结果应该是:
    You have bunnies cute
    I have puppies cute
    I have two kitties
    You have three bunnies cute 
    I have three puppies cute
    I have four kitties
    

答案1

使用 GNU sed

sed 'h; s/puppies/bunnies/g; T; s/I/You/; G' < your-file

答案2

使用sed, 并假设触发器是cute行尾的子字符串:

sed '/cute[[:blank:]]*$/ { h; s/^I/You/; s/[[:alpha:]]* cute/bunnies cute/; G; }' file

模式[[:blank:]]*中允许在行末尾使用尾随空格或制表符(第一行在问题中具有尾随空格)。

这将产生文本

You have bunnies cute
I have puppies cute
I have two kitties
You have three bunnies cute
I have three puppies cute
I have four kitties

h命令将当前行的副本保存在“保留空间”中。第一个s///命令将I行开头的 更改为,You而第二个命令更改以 开头的任何cute单词bunnies。该G命令最终将原始行从保留空间附加到当前(修改后的)行的末尾,中间有一个换行符。


变体:

sed '/[[:alpha:]]* \(cute[[:blank:]]*\)$/ { h; s//bunnies \1/; s/^I/You/; G; }' file

这利用了这样一个事实:如果您在命令中将正则表达式留空s///,则将使用最新的正则表达式。


puppies由字符串而不是触发的变体cute。这使得它稍微短一些:

sed '/puppies/ { h; s//bunnies/; s/^I/You/; G; }' file

答案3

使用awk

awk 'function prnt() { print edit ORS hold; hold=edit="" }
     hold            { prnt() }
     /puppies/       { hold=$0; $1="you"; gsub("puppies", "bunnies"); edit=$0; next }
END{ if(hold) prnt() }1' infile

答案4

gnu sedbranches

sed '
s/puppies/&/g; tfind
n
:find 
    h
    s/puppies/bunnies/g
    s/^I/You/
    G
'

gawk:

awk '$0~/puppies/ {

 original=$0
 sub(/puppies/, "bunnies")
 sub(/^I/, "You")
 print $0, original
 next
} 
{ print }
'

相关内容