替换来自其他文件内容的特定字符串之后的行

时间:2018-04-29 20:13:48

标签: awk sed

我有三个文本文件。

档案1

300,-4.45479329731605E-08,30.0000000534252
305,-3.24248685321522E-08,30.0000000626148
7505,-6.10348043414643E-08,29.9999998187525
7510,-2.97107304427854E-08,29.9999999033104

文件2

305
7510

当文件1中的行以文件2中的数字开头时,我想用文件3中的以下行替换文件1中的行

@1,2.0000,4.0
@2,10.0000,10.0

所需的输出是:

300,-4.45479329731605E-08,30.0000000534252
@1,2.0000,4.0
7505,-6.10348043414643E-08,29.9999998187525
@2,10.0000,10.0

修改:这些文件包含Windows行结尾。

3 个答案:

答案 0 :(得分:3)

$ cat tst.awk
BEGIN { FS=OFS="," }
{ sub(/\r$/,"") }
FILENAME == ARGV[1] { idx[FNR] = $1; next }
FILENAME == ARGV[2] { map[idx[FNR]] = $0; next }
$1 in map { $0 = map[$1] }
{ print }

$ awk -f tst.awk file2 file3 file1
300,-4.45479329731605E-08,30.0000000534252
@1,2.0000,4.0
7505,-6.10348043414643E-08,29.9999998187525
@2,10.0000,10.0

以上内容适用于任何操作系统上的任何awk。如果您想在输出中保留\r,请将sub()调用移至FILENAME==ARGV[1]块,以便仅影响file2

答案 1 :(得分:2)

<强>首先 可以方便地逐行合并文件2和文件3。您可以使用paste命令实现该目的:

paste -d"," file2 file3 > file23

根据您的示例,file2的内容:

305
7510

file3的内容:

@1,2.0000,4.0
@2,10.0000,10.0

file23的结果内容:

305,@1,2.0000,4.0
7510,@2,10.0000,10.0

<强>其次 然后,您可以使用简单的AWK脚本来执行所需操作:

awk -v FS="," 'NR==FNR { d[$1]=substr($0,length($1)+2); next } d[$1] { $0=d[$1] } 1' file23 file1

file1的内容:

300,-4.45479329731605E-08,30.0000000534252
305,-3.24248685321522E-08,30.0000000626148
7505,-6.10348043414643E-08,29.9999998187525
7510,-2.97107304427854E-08,29.9999999033104

输出:

300,-4.45479329731605E-08,30.0000000534252
@1,2.0000,4.0
7505,-6.10348043414643E-08,29.9999998187525
@2,10.0000,10.0

P.S。一般来说,像你这样的问题被认为是偏离主题的,因为你没有表现出任何自己解决问题的尝试。你应该在这样的问题中加入代码。

答案 2 :(得分:2)

在awk中:

$ awk -F, 'NR==FNR{a[$1];next}$1 in a{getline < "file3"}1' file2 file1
300,-4.45479329731605E-08,30.0000000534252
@1,2.0000,4.0
7505,-6.10348043414643E-08,29.9999998187525
@2,10.0000,10.0

说明:

$ awk -F, '               # comma delimiter
NR==FNR {                 # process file2
    a[$1]                 # hash to a 
    next                  # process next record in file2
}
$1 in a {                 # process file1. if first field value is in a
    getline < "file3"     # read a record from file3 and *)
}1' file2 file1           # output. mind the file order

*)如果file3中没有记录,则会输出空记录。

编辑:GNU awk的Windows固定变体(以及在Windows中未经测试的mawk):

$ awk 'BEGIN{FS=",";RS="\r\n"} NR==FNR{a[$1];next}$1 in a{getline < "file3"}1' file2 file1