[英]If string is found in line, replace with string from previous line, sed
我有数千行代码分布在需要更新的多个文件中。 现在他们就像这样:
active_data(COPIED),
我需要将COCOPED的所有实例(仅在这些行中)替换为上一行中括号内的文本。 因此,总的来说,当前的代码可能如下所示:
current_data(FOO|BAR|TEXT),
active_data(COPIED),
我希望它看起来像:
current_data(FOO|BAR|TEXT),
active_data(FOO|BAR|TEXT),
我可以很容易地找到要替换的行,可以用一些静态字符串替换,这没有问题,但是我不确定如何从前一行中提取数据并使用它。 我敢肯定它很简单,但是还不太清楚。 谢谢您的帮助。
(如果sed不起作用,我也可以看到使用AWK或其他方法,但我认为sed是一次更改的最佳解决方案)。
sed
可以工作,但是awk
更自然:
$ awk -F'[()]' '$2 == "COPIED" {sub(/COPIED/, prev)} {prev=$2;} 1' file
current_data(FOO|BAR|TEXT),
active_data(FOO|BAR|TEXT),
-F'[()]'
使用开放式或宽松的括号作为字段分隔符。
$2 == "COPIED" {sub("COPIED", prev)}
如果第二个字段已COPIED
,则将其替换为prev
。
prev=$2
更新prev
。
1
这是个隐秘的缩写,表示打印行。 等效于{print $0;}
。
$ awk -F'[()]' '{for (i=1;i<=NF;i++)printf "Line %s Field %s=%s\n",NR,i,$i;}' file
Line 1 Field 1=current_data
Line 1 Field 2=FOO|BAR|TEXT
Line 1 Field 3=,
Line 2 Field 1=active_data
Line 2 Field 2=COPIED
Line 2 Field 3=,
for file in *
do
awk -F'[()]' '$2 == "COPIED" {sub("COPIED", prev)} {prev=$2;} 1' "$file" >tmp$$ && mv tmp$$ "$file"
done
或者,如果您拥有现代的GNU awk:
awk -i inplace -F'[()]' '$2 == "COPIED" {sub("COPIED", prev)} {prev=$2;} 1' *
这可能对您有用(GNU sed):
sed 'N;s/\((\([^)]*\)).*\n.*(\)COPIED/\1\2/;P;D' file
这将在整个文件的整个长度中保持2行移动窗口的打开,并使用模式匹配来实现所需的结果。
使用GNU awk for FPAT:
$ awk -v FPAT='[(][^)]*[)]|[^)(]*' -v OFS= '$2=="(COPIED)"{$2=prev} {prev=$2; print}' file
current_data(FOO|BAR|TEXT),
active_data(FOO|BAR|TEXT),
与其他awk:
$ awk '
match($0,/\([^)]*\)/) {
curr = substr($0,RSTART,RLENGTH)
if (curr == "(COPIED)") {
$0 = substr($0,1,RSTART-1) prev substr($0,RSTART+RLENGTH)
}
else {
prev = curr
}
}
{ print }
' file
current_data(FOO|BAR|TEXT),
active_data(FOO|BAR|TEXT),
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.