【问题标题】:replace a particular row and column value of one file with another用另一个文件替换一个文件的特定行和列值
【发布时间】:2014-09-28 21:09:51
【问题描述】:

我有一个文件包含

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

【问题讨论】:

  • 请说明在所需的转换后它将如何处理。
  • 你忘记你使用什么语言了吗? (标记为 perl awk sed shell):)
  • @MarkSetchell 添加了我的最终输出。
  • @jm666:来自 awk 或 sed 语言。无论如何,谢谢我从 John1024 那里得到了很好的回答

标签: shell awk sed


【解决方案1】:
$ 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. 使用-v 选项将输出字段分隔符 (OFS) 指定为选项卡:-v OFS="\t"

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

【讨论】:

  • 谢谢。但是如果我需要用 tab 打印每个单词,我该怎么办?
  • @ramkrishna 答案更新为制表符分隔的版本。
  • 我只想感谢,因为通过这篇文章我学到了很多关于 awk 命令工作的知识。它对我帮助很大。再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-07-12
  • 2023-03-07
  • 2018-01-22
  • 1970-01-01
  • 2012-04-13
  • 1970-01-01
  • 2019-10-27
相关资源
最近更新 更多