linux - 如果匹配,则在文件中搜索字符串用某个字符串替换同一行中的另一个字符串

标签 linux sed awk grep tcl

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 如果它与该行上的任何行匹配将初始 h 替换为 d

最佳答案

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

但是,这将同时将所有数据保存在内存中。

关于linux - 如果匹配,则在文件中搜索字符串用某个字符串替换同一行中的另一个字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16691031/

相关文章:

shell - 从校验和输出中的文件名中去除目录

android - For循环多个数组并保留空行

xml - 如何计算一个单词在xml文件中出现了多少次

linux - 为什么不使用 grep -r -e filename 查找名为 "filename"的文件?

python - 在使用 Python 2.7 multiprocessing.Process 和日志记录的 Linux 上,日志记录如何/为什么是顺序的?

BASH:找到第一个字符串后在文件中查找一个字符串

linux - 如何让 Eclipse 识别 KBUILD_MODNAME?

sed 将模式移动到行首

shell - 带有选项 -i 和标志/d 设置的 sed

shell - 如何在 UNIX 中将两个行号之间的文本打印到新文件中