我有几千行代码分布在需要更新的多个文件中。现在他们是这样的:
active_data(COPIED),
我需要将复制的所有实例(仅在这些行中)替换为前一行括号内的文本。因此,当前的代码总数可能如下所示:
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如何看待田野
$ 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' *
关于regex - 如果在行中找到字符串,请用前一行sed的字符串替换,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31843909/