I have a few thousand lines of code spread out across multiple files that I need to update. Right now they are like so:
active_data(COPIED),
I need to replace all instances of COPIED (only in these lines) with the text inside the parenthesis on the previous line. So it total the code currently might look like:
current_data(FOO|BAR|TEXT),
active_data(COPIED),
and I want it to look like:
current_data(FOO|BAR|TEXT),
active_data(FOO|BAR|TEXT),
I can find the lines to be replaced easily enough, and could replace the with some static string with no problem, but I'm not sure how to pull the data from the previous line and use that. I'm sure its pretty simple but can't quite figure it out. Thanks for the help.
(I could see using AWK or something else for this too if sed won't work but I figure sed would be the best solution for a one time change).
sed
could work but awk
is more natural:
$ awk -F'[()]' '$2 == "COPIED" {sub(/COPIED/, prev)} {prev=$2;} 1' file
current_data(FOO|BAR|TEXT),
active_data(FOO|BAR|TEXT),
-F'[()]'
Use open or claose parens as the field separator.
$2 == "COPIED" {sub("COPIED", prev)}
If the second field is COPIED
, then replace it with prev
.
prev=$2
Update prev
.
1
This is cryptic shorthand which means print the line. It is equivalent to {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
Or, if you have a modern GNU awk:
awk -i inplace -F'[()]' '$2 == "COPIED" {sub("COPIED", prev)} {prev=$2;} 1' *
This might work for you (GNU sed):
sed 'N;s/\((\([^)]*\)).*\n.*(\)COPIED/\1\2/;P;D' file
This keeps a moving window of 2 lines open throughout the length of the file and uses pattern matching to effect the required result.
With 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),
With other awks:
$ 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),
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.