我需要找到一种方法来复制包含小编辑字符串的文件中的行。受骗者必须出现在原始行上方。会是我最好的选择sed
吗?awk
理想情况下,在新行中替换puppies
为,并替换为。bunnies
I
You
例如:
- 输入文件:
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 sed
和branches
:
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 }
'