Shell每n行插入一行

5

我有两个文件,正在尝试将 file2 中的一行插入到 file1 中,从 file1 开始的每四行中的另一个一行。例如:

file1:

line 1
line 2
line 3
line 4
line 5
line 6
line 7
line 8
line 9
line 10

文件2:

50
43
21

我想要得到的输出结果:

50
line 1
line 2
line 3
line 4
43
line 5
line 6
line 7
line 8
21
line 9
line 10

The code I have:

while read line
do
    sed '0~4 s/$/$line/g' < file1.txt > file2.txt
done < file1.txt

我遇到了以下错误:
sed: 1: "0~4 s/$/$line/g": invalid command code ~

它从另一个文件中读取。在这种情况下,是file1文件。 - jeabesli
你能同时展示一下file1的样本数据吗? - anubhava
1
我修改了问题,因为我的文件混淆了。 - jeabesli
下面使用awk发布了一个答案。 - anubhava
5个回答

2
以下步骤不会将任何一个文件加载到内存数组中,而是同时遍历两个文件:

以下步骤不会将任何一个文件加载到内存数组中,而是同时遍历两个文件:

awk '(NR-1)%4==0{getline this<"file2";print this} 1' file1

如果你实际使用的 file2 文件比你想要在内存中保存的更大,那么这可能是更可取的。

具体分解如下:

  • (NR-1)%4==0 - 该条件匹配从0开始的每4行
  • getline this<"file2" - 从 "file2" 获取一行并将其存储在变量 this
  • print this - 打印...this
  • 1 - 简写为“打印当前行”,在本例中为来自 file1 的(awk 的正常输入)

2

使用 awk 很容易实现这一点:

awk 'FNR==NR{a[i++]=$0; next} !((FNR-1) % 4){print a[j++]} 1' file2 file1

50
line 1
line 2
line 3
line 4
43
line 5
line 6
line 7
line 8
21
line 9
line 10
  • 在处理输入的第一个文件 file2 时,我们将每一行存储在数组中,并使用从0开始的递增数字作为键。
  • 在处理输入的第二个文件 file1 时,我们使用模运算检查当前记录号是否可以被4整除,如果可以,则插入来自 file2 的一行并增加索引计数器。
  • 最后,使用动作 1,我们打印来自file1的行。

2
这可能适用于你(GNU sed):
sed -e 'Rfile1' -e 'Rfile1' -e 'Rfile1' -e 'Rfile1' file2

或者只需使用复制和粘贴:
cat file1 | paste -d\\n file2 - - - -

1
另一种使用Unix工具链的选择。
$ paste file2 <(pr -4ats file1) | tr '\t' '\n'

50
line 1
line 2
line 3
line 4
43
line 5
line 6
line 7
line 8
21
line 9
line 10

-1
这是一个使用 pastetr 来实现的幽默方式。
paste file2 <(paste - - - - <file1) | tr '\t' '\n'

假设您的输入文件中没有任何实际制表符。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接