用于在两个文件中获取命令值并写入新文件的模式的 Bash 脚本
需要 bash 脚本来查找两个文件中的公共值并以特定模式将其写入新文件。我可以获得共同的价值观,但无法让模式发挥作用。
$ cat file1
1
2
3
4
6
7
8
10
12
13
16
20
21
22
23
27
30
$ cat file2
1
2
3
4
8
10
12
13
16
20
21
22
23
27
Desired output:
1:4
8
10
12:13
16
20:23
27
要获得共同点,您可以执行一些简单的操作,例如
awk 'NR==FNR{x[$1]=1} NR!=FNR && x[$1]' file1 file2
这给您留下了一个列表,您需要对范围内的元素进行分组。这是一个简单的 awk 脚本:
awk 'NR==1 {s=l=$1; next} $1!=l+1 {if(l == s) print l; else print s ":" l; s=$1} {l=$1} END {if(l == s) print l; else print s ":" l; s=$1}'
把它们放在一起:
awk 'NR==FNR{x[$1]=1} NR!=FNR && x[$1]' file1 file2 | awk 'NR==1 {s=l=$1; next} $1!=l+1 {if(l == s) print l; else print s ":" l; s=$1} {l=$1} END {if(l == s) print l; else print s ":" l; s=$1}'
解释:
我们跟踪当前范围的开始和我们看到的最后一个值。
NR==1 {s=l=$1; next}
NR==1 仅在第一行运行。它始终是范围的第一个元素。接下来跳过其他命令。
$1!=l+1 {if(l == s) print l; else print s ":" l; s=$1}
如果运行中有中断,那么给定行的值 ($1) 将不是最后一行 (l + 1) 之后的值,因此我们打印出范围。如果开始和结束相同,我们打印出一个数字;否则我们打印出开始,然后是冒号,然后是结束。
{l=$1}
我们在进行范围检查后更新最后一行。
END {if(l == s) print l; else print s ":" l; s=$1}
我们必须在最后再运行一次逻辑以打印出最后一个范围