通过在 grep 之后组合替换行中的工作
Replace work in line by combining after grep
我需要在执行 grep 并得到结果的最后一行后替换一个词。
这是我的示例文件:
aaa ts1 ts2
bbb ts3 ts4
aaa ts5 ts6
aaa ts7 NONE
我需要的是 select 所有包含 'aaa' 的行,得到结果中的最后一行并替换 NONE.
我试过了
cat <file> | grep "aaa" | tail -n 1 | sed -i 's/NONE/ts8/g'
但是没用。
有什么建议吗?
谢谢
使用 tac
+ awk
解决方案请尝试以下。
tac Input_file | awk '/aaa/ && ++count==1{sub(/NONE/,"ts8")} 1' | tac
一旦您对上述命令感到满意,请尝试执行以下操作,就地保存到 Input_file。
tac Input_file | awk '/aaa/ && ++count==1{sub(/NONE/,"ts8")} 1' | tac > temp && mv temp Input_file
解释: 首先由 tac
以相反的顺序打印 Input_file 然后将其标准输出发送到 awk
作为输入,在第一行(实际上是包含 aaa
的最后一行)中将 NONE 替换为 ts8。简单地打印所有其他行,再次将输出发送到 tac
以使其符合 Input_file 的实际顺序。
为了在单个命令中执行此操作,这应该适用于 awk
的任何版本:
awk 'FNR==NR {if (=="aaa") n=FNR; next} FNR == n {="TS7"} 1' file{,}
aaa ts1 ts2
bbb ts3 ts4
aaa ts5 ts6
aaa ts7 TS7
要在同一文件中保存输出,请使用:
awk 'FNR==NR {if (=="aaa") n=FNR; next}
FNR == n {="TS7"} 1' file{,} > file.out && mv file.out file
或使用gnu sed
,您可以使用:
sed -i -Ez 's/(.*\naaa[[:blank:]]+[^[:blank:]]+[[:blank:]]+)NONE/ts8/' file
cat file
aaa ts1 ts2
bbb ts3 ts4
aaa ts5 ts6
aaa ts7 ts8
如果想获取开头匹配aaa的最后一行,可以遍历所有行,在END块中,打印最后一次出现的地方,将NONE
替换为ts8
使用 awk:
awk '=="aaa"{last=[=10=]}END{sub(/NONE/,"ts8",last);print last}' file
部分:
=="aaa" { # If the first field is aaa
last=[=11=] # Set variable last to the whole line (overwrite on each match)
}
END { # Run once at the end
sub(/NONE/,"ts8",last) # Replace NONE with ts8 in the last variable
print last
}
' file
输出
aaa ts7 ts8
我需要在执行 grep 并得到结果的最后一行后替换一个词。
这是我的示例文件:
aaa ts1 ts2
bbb ts3 ts4
aaa ts5 ts6
aaa ts7 NONE
我需要的是 select 所有包含 'aaa' 的行,得到结果中的最后一行并替换 NONE.
我试过了
cat <file> | grep "aaa" | tail -n 1 | sed -i 's/NONE/ts8/g'
但是没用。
有什么建议吗?
谢谢
使用 tac
+ awk
解决方案请尝试以下。
tac Input_file | awk '/aaa/ && ++count==1{sub(/NONE/,"ts8")} 1' | tac
一旦您对上述命令感到满意,请尝试执行以下操作,就地保存到 Input_file。
tac Input_file | awk '/aaa/ && ++count==1{sub(/NONE/,"ts8")} 1' | tac > temp && mv temp Input_file
解释: 首先由 tac
以相反的顺序打印 Input_file 然后将其标准输出发送到 awk
作为输入,在第一行(实际上是包含 aaa
的最后一行)中将 NONE 替换为 ts8。简单地打印所有其他行,再次将输出发送到 tac
以使其符合 Input_file 的实际顺序。
为了在单个命令中执行此操作,这应该适用于 awk
的任何版本:
awk 'FNR==NR {if (=="aaa") n=FNR; next} FNR == n {="TS7"} 1' file{,}
aaa ts1 ts2
bbb ts3 ts4
aaa ts5 ts6
aaa ts7 TS7
要在同一文件中保存输出,请使用:
awk 'FNR==NR {if (=="aaa") n=FNR; next}
FNR == n {="TS7"} 1' file{,} > file.out && mv file.out file
或使用gnu sed
,您可以使用:
sed -i -Ez 's/(.*\naaa[[:blank:]]+[^[:blank:]]+[[:blank:]]+)NONE/ts8/' file
cat file
aaa ts1 ts2
bbb ts3 ts4
aaa ts5 ts6
aaa ts7 ts8
如果想获取开头匹配aaa的最后一行,可以遍历所有行,在END块中,打印最后一次出现的地方,将NONE
替换为ts8
使用 awk:
awk '=="aaa"{last=[=10=]}END{sub(/NONE/,"ts8",last);print last}' file
部分:
=="aaa" { # If the first field is aaa
last=[=11=] # Set variable last to the whole line (overwrite on each match)
}
END { # Run once at the end
sub(/NONE/,"ts8",last) # Replace NONE with ts8 in the last variable
print last
}
' file
输出
aaa ts7 ts8