简体   繁体   中英

Copy value from previous line using awk/sed

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM