2
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

在这里我需要搜索-s 0 -d 29 -p cbr 如果它与该行上的任何行匹配用d替换初始h

4

7 回答 7

4

使用 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"]

但是,这将一次将所有数据保存在内存中。

于 2013-05-22T18:45:24.750 回答
3

如果该行与模式匹配并且第一个字段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
于 2013-05-22T11:57:26.283 回答
2

试试下面的 sed 单线:

sed '/-s 0 -d 29 -p cbr/s/^h/d/' file
于 2013-05-22T11:59:45.190 回答
0

快速回答,我不能在这里测试,比如:

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

应该管用。让我知道或编辑。我只能稍后再检查。祝你好运!

于 2013-05-22T11:58:29.333 回答
0

你可以试试这个,

sed  '/-s 0 -d 29 -p cbr/{s/^h\(.*\)/d\1/g}' file
于 2013-05-22T11:58:40.063 回答
0

通过initial h,您似乎指的是匹配行中的第一个字符。根据这个假设,以下应该有效:

grep -- "-s 0 -d 29 -p cbr" inputfile | sed 's/^h/d/'
于 2013-05-22T11:59:03.397 回答
0

这可能对您有用(GNU sed):

sed -r 's/^h(.*-s 0 -d 29 -p cbr)/d\1/' file
于 2013-05-22T21:30:32.263 回答