例子
文件1:
This Dog
This Cat
This Duck
This Horse
文件2:
...
Animal Name
...
AniMal Type
...
AnIMal Class
...
animal Brand
...
我想做以下事情:
- 在第一次出现“Animal”的下方添加文件 1(这只狗)的第 1 行(忽略大小写)
- 在第二次出现的“Animal”下方添加文件 1(这只猫)的第 2 行(忽略大小写)
- 将文件 1 (This Duck) 的第 3 行添加到第 3 次出现的“Animal”下方(忽略大小写)
- 在第 4 次出现的“Animal”下方添加文件 1(这匹马)的第 4 行(忽略大小写)
- ...
因此,一般来说,文件 1 的第 n 行应添加到第 n 次出现的“Animal”下方(忽略大小写)。
那么,如何使用“sed”或“awk”或 Linux 中的任何命令来实现此目的?
答案1
使用 GNU sed:
$ sed '/^animal/IR File1' File2
...
Animal Name
This Dog
...
AniMal Type
This Cat
...
AnIMal Class
This Duck
...
animal Brand
This Horse
...
其中 GNU 扩展如下:
正则表达式匹配的 I 修饰符是一个 GNU 扩展,它导致正则表达式以不区分大小写的方式进行匹配。
和
R 文件名
在当前周期结束时或在读取下一个输入行时将要读取的文件名行排队并插入到输出流中。请注意,如果无法读取文件名,或者到达其结尾,则不会附加任何行,并且不会出现任何错误指示。
答案2
这awk解决方案应该可以解决问题:
awk 'NR==FNR{a[NR]=$0;next};1;tolower($1)=="animal"{print a[++i]}' file1 file2 > file3
NR==FNR{a[NR]=$0;下一个}将 file1 数据累积在数组中,跳到下一个输入行以防止在此阶段处理 file2。
1打印 file2 的每个输入行。
tolower($1)=="动物"{print a[++i]}不区分大小写地匹配“animal”,并输出相应的数组项,预先递增数组索引。
答案3
塞德
只需.
在最后一行后添加一个file_1
来表示 file_1 的结束,sed
因为sed
没有 的概念FNR
,awk
IOW,sed
该POSIX
品种无法知道一个文件何时结束以及下一个文件何时开始。
基本思想是将动物名称存储在 中hold area
,然后当需要读取 中时,file_2
我们抓取 中每个换行符分隔的部分hold
并将其附加到 中pattern space
,同时将detach
其从 中读取hold
。此练习仅在以不区分大小写的方式attach<->detach
组成文字字符串的行上进行。animal
sed -e '
1{
:file1
N
/\n\.$/!bfile1
s///;h;d
}
/^[aA][nN][iI][mM][aA][lL]/!b
G
s/\n/&&/2;ta
b
:a
h;s/.*\n\n//;x
s/\n\n.*//
' file_1 file_2