Any ideas how to write a awk/sed script to replace a particular sentinel value or pattern (in this case PREV
from a value in a different column from the previous line?)
eg replace all PREVs
from the value from first column of the previous line
a -> b
c -> PREV
d -> PREV
to:
a -> b
c -> a
d -> c
$ awk 'NR>1{$3=p} {p=$1} 1' file
a -> b
c -> a
d -> c
$ cat file
a -> b
c -> PREV
d -> PREV
e -> f # watch this record
g -> PREV
To replace all PREV
s from the value from first column of the previous line using awk:
$ awk '$3=="PREV"{$3=prev}{prev=$1}1' file
Output:
a -> b
c -> a
d -> c
e -> f # watch this record
g -> e
Golf'd:
$ awk '$3=p?p:$3; {p=$1}' file
a -> b
c -> a
d -> c
to account for $1==0
:
$ awk '$3 = length(p)? p: $3; {p=$1}' <<EOF
a -> b
c -> PREV
d -> PREV
0 -> PREV
e -> PREV
f -> PREV
EOF
a -> b
c -> a
d -> c
0 -> d
f -> e
With GNU sed:
sed -E '/PREV/{G;s/PREV(.*)\n(\S+).*/\2\1/};h' infile
Explained:
/PREV/ { # if the current line matches PREV
G # append hold space to pattern space
s/PREV(.*)\n(\S+).*/\2\1/ # replace PREV with first word from appended line,
# drop newline and rest of appended line
}
h # store pattern space in hold space
Or, with slight modifications for portability:
sed '/PREV/{G;s/PREV\(.*\)\n\([^[:blank:]]\{1,\}\).*/\2\1/;};h' infile
如果您的数据在d
文件中,请尝试使用gnu sed:
sed -Ez ':s s/((\S+)\s*->[^\n]+\n[^\n]*)PREV\s*/\1\2\n/;ts' d
For this content
$ cat file
a -> b
c -> PREV
d -> PREV
e -> PREV
g -> GOLD
p -> m
Ensure that only PREV sentinel are replaced(others left as it is):
$ awk 'NR>1 && /PREV/{$3=p}{p=$1} 1' file
a -> b
c -> a
d -> c
e -> d
g -> GOLD
p -> m
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.