使用awk从两个文件中添加列
Adding columns from two file with awk
我有以下问题:
假设我有两个具有以下结构的文件:
1 17.650 0.001 0.000E+00
1 17.660 0.002 0.000E+00
1 17.670 0.003 0.000E+00
1 17.680 0.004 0.000E+00
1 17.690 0.001 0.000E+00
1 17.700 0.000 0.000E+00
1 17.710 0.004 0.000E+00
1 17.720 0.089 0.000E+00
1 17.730 0.011 0.000E+00
1 17.740 0.000 0.000E+00
1 17.750 0.032 0.000E+00
1 17.760 0.100 0.000E+00
1 17.770 0.020 0.000E+00
1 17.780 0.002 0.000E+00
2 -20.000 0.001 0.000E+00
2 -19.990 0.002 0.000E+00
2 -19.980 0.003 0.000E+00
2 -19.970 0.004 0.000E+00
2 -19.960 0.001 0.000E+00
2 -19.950 0.000 0.000E+00
2 -19.940 0.004 0.000E+00
2 -19.930 0.089 0.000E+00
2 -19.920 0.011 0.000E+00
2 -19.910 0.000 0.000E+00
2 -19.900 0.032 0.000E+00
2 -19.890 0.100 0.000E+00
2 -19.880 0.020 0.000E+00
2 -19.870 0.002 0.000E+00
两个文件的前两列相同,不同的是第 3 列和第 4 列。以上是这些文件的示例。该空行是必不可少的,可以在将数据分成“块”的整个文件中找到。它必须存在!
使用以下命令:
awk '{a[FNR]=; b[FNR]=; s[FNR]+=} END{for (i=1; i<=FNR; i++) print a[i], b[i], s[i]}' file1 file2 > file-result
我正在尝试创建一个文件,其中第 1 列和第 2 列与原始文件中的列相同,第 3 列是 file1 和 file2 中第 3 列的总和。
如果没有空行,此命令有效。使用空白行我得到以下内容:
1 17.650 0.001
1 17.660 0.002
1 17.670 0.003
1 17.680 0.004
1 17.690 0.001
1 17.700 0.000
1 17.710 0.004
1 17.720 0.089
1 17.730 0.011
1 17.740 0.000
1 17.750 0.032
1 17.760 0.100
1 17.770 0.020
1 17.780 0.002
0
2 -20.000 0.001
2 -19.990 0.002
2 -19.980 0.003
2 -19.970 0.004
2 -19.960 0.001
2 -19.950 0.000
2 -19.940 0.004
2 -19.930 0.089
2 -19.920 0.011
2 -19.910 0.000
2 -19.900 0.032
2 -19.890 0.100
2 -19.880 0.020
2 -19.870 0.002
(请注意,在上面的第 3 列中我没有写出实际金额,但你明白了)
如何确保0
不出现在空行中?想不通了。
请注意,如果前 2 列确实相同,则无需将它们存储在数组中;仅存储第一个文件的第 3 列。
您的问题的解决方案很简单:在处理第二个文件时测试该行是否为空白,如果是,则打印它。否则打印修改后的行。 next
声明使所有这些变得非常简单和干净。
awk 'NR == FNR {s[NR]=; next}
/^[[:space:]]*$/ {print; next}
{print , , s[FNR]+}' file1 file2 > file-result
第一个块 运行 仅在第一个文件的行中(NR == FNR
仅在那时为真)。它将第 3 个字段存储在数组 s
中,由行号索引。 next
语句立即移动到下一行并阻止其他两个块到第一个文件的行上的 运行。
因此第二个块 运行 仅在第二个文件的行上,并且仅当它们为空白时(^[[:space:]]*$
表示开头之间只有 0 个或更多空格(^
)和行尾($
))。该块按原样打印一个空行,next
语句再次立即移动到下一行,防止最后一个块到 运行。请注意,如果您的 awk 支持 \s
运算符,您可以将 [[:space:]]
替换为 \s
。另请注意,测试也可以是 NF == 0
(NF
是当前记录的字段数)。
所以第三个和最后一个块 运行 仅在第二个文件的非空行上。它只是打印两个文件的前两个字段和第三个字段的总和(取自 </code> 和 <code>s
数组)。
我有以下问题:
假设我有两个具有以下结构的文件:
1 17.650 0.001 0.000E+00
1 17.660 0.002 0.000E+00
1 17.670 0.003 0.000E+00
1 17.680 0.004 0.000E+00
1 17.690 0.001 0.000E+00
1 17.700 0.000 0.000E+00
1 17.710 0.004 0.000E+00
1 17.720 0.089 0.000E+00
1 17.730 0.011 0.000E+00
1 17.740 0.000 0.000E+00
1 17.750 0.032 0.000E+00
1 17.760 0.100 0.000E+00
1 17.770 0.020 0.000E+00
1 17.780 0.002 0.000E+00
2 -20.000 0.001 0.000E+00
2 -19.990 0.002 0.000E+00
2 -19.980 0.003 0.000E+00
2 -19.970 0.004 0.000E+00
2 -19.960 0.001 0.000E+00
2 -19.950 0.000 0.000E+00
2 -19.940 0.004 0.000E+00
2 -19.930 0.089 0.000E+00
2 -19.920 0.011 0.000E+00
2 -19.910 0.000 0.000E+00
2 -19.900 0.032 0.000E+00
2 -19.890 0.100 0.000E+00
2 -19.880 0.020 0.000E+00
2 -19.870 0.002 0.000E+00
两个文件的前两列相同,不同的是第 3 列和第 4 列。以上是这些文件的示例。该空行是必不可少的,可以在将数据分成“块”的整个文件中找到。它必须存在!
使用以下命令:
awk '{a[FNR]=; b[FNR]=; s[FNR]+=} END{for (i=1; i<=FNR; i++) print a[i], b[i], s[i]}' file1 file2 > file-result
我正在尝试创建一个文件,其中第 1 列和第 2 列与原始文件中的列相同,第 3 列是 file1 和 file2 中第 3 列的总和。
如果没有空行,此命令有效。使用空白行我得到以下内容:
1 17.650 0.001
1 17.660 0.002
1 17.670 0.003
1 17.680 0.004
1 17.690 0.001
1 17.700 0.000
1 17.710 0.004
1 17.720 0.089
1 17.730 0.011
1 17.740 0.000
1 17.750 0.032
1 17.760 0.100
1 17.770 0.020
1 17.780 0.002
0
2 -20.000 0.001
2 -19.990 0.002
2 -19.980 0.003
2 -19.970 0.004
2 -19.960 0.001
2 -19.950 0.000
2 -19.940 0.004
2 -19.930 0.089
2 -19.920 0.011
2 -19.910 0.000
2 -19.900 0.032
2 -19.890 0.100
2 -19.880 0.020
2 -19.870 0.002
(请注意,在上面的第 3 列中我没有写出实际金额,但你明白了)
如何确保0
不出现在空行中?想不通了。
请注意,如果前 2 列确实相同,则无需将它们存储在数组中;仅存储第一个文件的第 3 列。
您的问题的解决方案很简单:在处理第二个文件时测试该行是否为空白,如果是,则打印它。否则打印修改后的行。 next
声明使所有这些变得非常简单和干净。
awk 'NR == FNR {s[NR]=; next}
/^[[:space:]]*$/ {print; next}
{print , , s[FNR]+}' file1 file2 > file-result
第一个块 运行 仅在第一个文件的行中(NR == FNR
仅在那时为真)。它将第 3 个字段存储在数组 s
中,由行号索引。 next
语句立即移动到下一行并阻止其他两个块到第一个文件的行上的 运行。
因此第二个块 运行 仅在第二个文件的行上,并且仅当它们为空白时(^[[:space:]]*$
表示开头之间只有 0 个或更多空格(^
)和行尾($
))。该块按原样打印一个空行,next
语句再次立即移动到下一行,防止最后一个块到 运行。请注意,如果您的 awk 支持 \s
运算符,您可以将 [[:space:]]
替换为 \s
。另请注意,测试也可以是 NF == 0
(NF
是当前记录的字段数)。
所以第三个和最后一个块 运行 仅在第二个文件的非空行上。它只是打印两个文件的前两个字段和第三个字段的总和(取自 </code> 和 <code>s
数组)。