将文件的特定行替换为其他文件的值

将文件的特定行替换为其他文件的值

我想用file1每行中的值替换第 2、第 6 和第 7 行file2,并生成一系列等于wc -l file2

cat file1
w
3
y
G
7
1.2
Q
cat file2
1        1        1
6        6        7
5        6        5

预期的结果:

cat out1
w
1
y
G
7
1
1
cat out2
w
6
y
G
7
6
7
cat out3
w
5
y
G
7
6
5

答案1

awk '
    FNR == NR { data[++n] = $0; next }
    {
        data[2] = $1; data[6] = $2; data[7] = $3;
        outname = sprintf("out%d", FNR)  # or: outname = "out" FNR
        for (i = 1; i <= n; ++i)
            print data[i] >outname
        close(outname)
    }' file1 file2

这首先阅读file1,然后file2

在读取file1FNR == NR块)时,代码所做的唯一事情awk是将每一行存储在数组中data

读取时file2,代码将获取该文件的一行上的三个字段中的每一个,并将它们分配给与data要更改的行相对应的索引file1

然后,存储的行将data打印到通过获取当前行号file2并在其前面添加字符串而构造的文件名out

close(outname)仅当您使用awk非 GNU 的awk,并且写入的文件数量超过打开文件描述符的限制(超过ulimit -n返回的数量,对于标准流减去三个)时,才真正需要。

测试:

$ tree
.
|-- file1
`-- file2

0 directory, 2 files
$ awk '
    FNR == NR { data[++n] = $0; next }
    {
        data[2] = $1; data[6] = $2; data[7] = $3;
        outname = sprintf("out%d", FNR)
        for (i = 1; i <= n; ++i)
            print data[i] >outname
        close(outname)
    }' file1 file2
$ tree
.
|-- file1
|-- file2
|-- out1
|-- out2
`-- out3

0 directory, 5 files
$ paste out[123]
w       w       w
1       6       5
y       y       y
G       G       G
7       7       7
1       6       6
1       7       5

答案2

$ cat tst.awk
BEGIN {
    split("2 6 7",tmp)
    for (fldNr in tmp) {
        map[tmp[fldNr]] = fldNr
    }
}
NR==FNR {
    rows[++numRows] = $i
    next
}
{
    out = "out" FNR
    for (rowNr=1; rowNr<=numRows; rowNr++) {
        print (rowNr in map ? $(map[rowNr]) : rows[rowNr]) > out
    }
    close(out)
}

$ awk -f tst.awk file1 file2

$ head out?
==> out1 <==
w
1
y
G
7
1
1

==> out2 <==
w
6
y
G
7
6
7

==> out3 <==
w
5
y
G
7
6
5

答案3

使用GNU sed我们在文件 out_0/1/2 中获取 file2 每一行的输出。

tmpf=$(mktemp) i=0
while read -ra a <&3
do
   printf '%s\n' "${a[@]}" > "$tmpf"
   sed -ne "
      $(printf '%dba\n' 2 6 7)
      p;d;:a
      R $tmpf
   " file1 > "out_$i"
    (( i++ ))
done 3< file2
  • 在 while 循环中读取 file2 并将字段从空格分隔转换为换行符分隔并存储在临时文件中。
  • get sed 对 file1 的第 2,6,&7 行调用 R 命令以获得所需的输出。

相关内容