用另一个文件替换一个文件的特定行和列值

时间:2014-09-28 21:09:52

标签: shell awk sed

我有一个包含

的文件
a b c d
g h i j
d e f f

和另一个包含

的文件
1 2 3 4
5 6 7 8
9 1 0 1

我知道我可以使用

提取特定的行和列
awk 'FNR == 2 {print $3}' fit_detail.txt

但是,我需要用第二个文件的第2行和第3列替换第一个文件的第2列和第3行。我怎么能这样做并将其保存到另一个文件中。

最后,我的输出应该看起来像

a b c d
g h i j
d 1 f f

1 个答案:

答案 0 :(得分:3)

$ awk 'NR==FNR && NR==3 {a=$2} NR==FNR {next} FNR==3 {$2=a} {print}' file2 file1
a b c d
g h i j
d 1 f f

说明:

  • NR==FNR && NR==3 {a=$2}

    awk中,NR是已经读取的记录(行)数,FNR是已从中读取的记录数(行)当前文件。所以,当NR==FNR时,我们知道我们正在处理命令行上命名的第一个文件。对于该文件,我们仅选择第三行(NR==3)并将其第二列的值保存在变量a中。

  • NR==FNR {next}

    如果我们在命令行上处理第一个命名文件,请跳至next行。

  • FNR==3 {$2=a}

    由于前面的next语句,如果我们现在正在处理第二个命名文件,则只能访问此命令。对于此文件,如果我们位于第三行,请将第二列更改为值a

  • {print}

    打印第二个指定文件中的所有行。

控制输出格式

默认情况下,awk将输出字段与空格分隔开。如果需要另一个输出字段分隔符(例如制表符),则可以按如下方式指定:

$ awk -v OFS="\t" 'NR==FNR && NR==3 {a=$2} NR==FNR {next} {$2=$2} FNR==3 {$2=a} {print}' file2 file1
a       b       c       d
g       h       i       j
d       1       f       f

为实现这一目标,我们进行了两项修改:

  1. 输出字段分隔符(OFS)已指定为包含-v选项的标签:-v OFS="\t"

  2. 使用简单的打印语句(例如{print})时,awk通常仅在行以某种方式更改时才应用新的输出字段分隔符。这是通过语句$2=$2完成的。这将第二个字段分配给自己。即使这使第二个字段保持不变,也足以触发awk`在输出时用新的字段分隔符替换旧的字段分隔符。