在一个文件中search一个string,如果匹配,用同一个stringreplace同一行中的另一个string

 h -t 9.641909323 -s 0 -d 29 -p cbr -e 1078 -c 2 -a 0 -i 169 -k MAC
 r -t 9.650534114 -s 29 -d 29 -p cbr -e 1020 -c 2 -a 0 -i 169 -k MAC
 + -t 9.650544114 -s 29 -d -1 -p ACK -e 38 -c 2 -a 0 -i 0 -k MAC 
 -  t 9.650544114 -s 29 -d -1 -p ACK -e 38 -c 2 -a 0 -i 0 -k MAC
 h -t 9.650544114 -s 29 -d -1 -p ACK -e 38 -c 2 -a 0 -i 0 -k MAC

在这里我需要search-s 0 -d 29 -p cbr,如果它与该行上的任何行匹配,则用dreplace最初的h

如果行匹配模式,并且第一个字段是h则将第一个字段设置为d

 $ awk '/-s 0 -d 29 -p cbr/&&$1=="h"{$1="d"}1' file d -t 9.641909323 -s 0 -d 29 -p cbr -e 1078 -c 2 -a 0 -i 169 -k MAC r -t 9.650534114 -s 29 -d 29 -p cbr -e 1020 -c 2 -a 0 -i 169 -k MAC + -t 9.650544114 -s 29 -d -1 -p ACK -e 38 -c 2 -a 0 -i 0 -k MAC - -t 9.650544114 -s 29 -d -1 -p ACK -e 38 -c 2 -a 0 -i 0 -k MAC h -t 9.650544114 -s 29 -d -1 -p ACK -e 38 -c 2 -a 0 -i 0 -k MAC 

编辑:

只取代第一场比赛:

 $ awk '/-s 0 -d 29 -p cbr/&&$1=="h"&&!f{$1="d";f=1}1' file d -t 9.641909323 -s 0 -d 29 -p cbr -e 1078 -c 2 -a 0 -i 169 -k MAC r -t 9.650534114 -s 29 -d 29 -p cbr -e 1020 -c 2 -a 0 -i 169 -k MAC + -t 9.650544114 -s 29 -d -1 -p ACK -e 38 -c 2 -a 0 -i 0 -k MAC - -t 9.650544114 -s 29 -d -1 -p ACK -e 38 -c 2 -a 0 -i 0 -k MAC h -t 9.650544114 -s 29 -d -1 -p ACK -e 38 -c 2 -a 0 -i 0 -k MAC 

使用Tcl,你可以编写比其他语言更长的程序:

 # Open the files for streaming... set filename "whatever.log" set fin [open $filename] set fout [file tempfile tempName] # Process the lines, one by one... while {[gets $fin line] >= 0} { ### <<< THIS IS IDIOMATIC FOR STREAMING if {[string first "-s 0 -d 29 -p cbr" $line]} { regsub "^h" $line "d" line } puts $fout $line } # Finalize everything close $fin close $fout file rename $tempName $filename 

如果你想输出到不同的文件,你可以使用:

 set fout [open "differentFile.txt" "w"] 

而不是set fout [file tempfile tempName]并省略file rename 。 (这也将使代码在8.6以前的所有版本的Tcl上工作; file tempfile是一个新功能,但是这里使用的所有东西已经存在很久了。)


或者,对于一次读入所有行的版本,用这个使用行模式RE替换和一点智能的单行代替中央处理循环:

 # Use [puts -nonewline] because the last newline is kept with [read] puts -nonewline $fout [regsub -all -line "^h(.*-s 0 -d 29 -p cbr)" [read $fin] "d\\1"] 

但是,这将一次保存所有的数据。

尝试以下sed单行:

 sed '/-s 0 -d 29 -p cbr/s/^h/d/' file 

你可以试试这个,

 sed '/-s 0 -d 29 -p cbr/{s/^h\(.*\)/d\1/g}' file 

按照最初的 h ,你似乎指的是匹配行中的第一个字符。 通过这个假设,以下应该工作:

 grep -- "-s 0 -d 29 -p cbr" inputfile | sed 's/^h/d/' 

快速回答,我不能在这里测试,像这样:

 sed '/-s 0 -d 29 -p cbr/s/^h/d/' 

应该管用。 让我知道或编辑。 我将可以稍后检查。 祝你好运!

这可能适用于你(GNU sed):

 sed -r 's/^h(.*-s 0 -d 29 -p cbr)/d\1/' file