Shell 合并文件,使表1中的行对表2中的每一行重复
不确定这两个表的连接的技术术语是什么(在google上花了很长时间)。 您可以用SQL编写它 从表1、表2中选择* 我有一张桌子Shell 合并文件,使表1中的行对表2中的每一行重复,shell,unix,join,awk,sed,Shell,Unix,Join,Awk,Sed,不确定这两个表的连接的技术术语是什么(在google上花了很长时间)。 您可以用SQL编写它 从表1、表2中选择* 我有一张桌子 Var1 1 2 3 &表2 Var2 6 7 8 我想合并/加入,所以我有 Var1 Var2 1 6 1 7 1 8 2 6 2 7 2 8 3 6 3 7 3 8 (即,每个var1对每个var2重复) 除了编写循环之外,还有没有像我在SQL中所做的那样简单的方法呢?使用awk的解决方案如下 awk 'FNR==NR{line[$0]++
Var1
1
2
3
&表2
Var2
6
7
8
我想合并/加入,所以我有
Var1 Var2
1 6
1 7
1 8
2 6
2 7
2 8
3 6
3 7
3 8
(即,每个var1对每个var2重复)
除了编写循环之外,还有没有像我在SQL中所做的那样简单的方法呢?使用awk的解决方案如下
awk 'FNR==NR{line[$0]++; next} {for (i in line) print $1, i} ' file2 file1
测试
$ cat file1
1
2
3
$ cat file2
6
7
8
$ awk 'FNR==NR{line[$0]++; next} {for (i in line) print $1, i} ' file2 file1
1 6
1 7
1 8
2 6
2 7
2 8
3 6
3 7
3 8
如果第一个文件足够小,可以放入内存中,您可以这样做
awk -v OFS='\t' '# Pesky header line
FNR==1 { if (NR==1) h=$0; else print h, $0; next }
NR==FNR { a[++i] = $0; next }
{ for (j=1; j<=i; ++j) print a[j], $0 }' table1 table2
(因为我很懒,所以这只会丢弃第一行。没有标题行会简化事情。)不,您最好希望的是:
$ awk 'NR==FNR{a[NR]=$0;next} FNR==1{print $0, a[1]; next} {for (i=2;i in a;i++) print $0, a[i]}' file2 file1
Var1 Var2
1 6
1 7
1 8
2 6
2 7
2 8
3 6
3 7
3 8
输入文件为:
$ cat file1
Var1
1
2
3
$ cat file2
Var2
6
7
8
下面是一个使用GNU并行和Bash实现它的有趣方法。我假设没有标题,因为这简化了问题(关于处理标题的一种方法,请参见下文) 无标题 首先,我们生成测试输入:
cat文件1
1.
2.
3.
表1结束
cat文件2
6.
7.
8.
表2结束
现在以文件作为输入参数运行parallel
:
parallel echo {1} {2} :::: file1 :::: file2
这导致:
1 6
1 7
1 8
2 6
2 7
2 8
3 6
3 7
3 8
带标题
为了处理标题和制表符分隔列,下面的解决方案基于给定的测试数据生成正确的结果
首先生成带有标题的测试数据:
cat << End-of-table1 > file1
Var1
1
2
3
End-of-table1
cat << End-of-table2 > file2
Var2
6
7
8
End-of-table2
输出:
Var1 Var2
1 6
1 7
1 8
2 6
2 7
2 8
3 6
3 7
3 8
GNU并行手册的相关部分
parallel[options][command[arguments]](::arguments |:::argfile))。。。
...
::参数
使用命令行中的参数作为输入源,而不是stdin
(标准输入)。与GNU并行的其他选项不同:::是
放置在命令之后和参数之前。
...
如果给定多个::,则每个组将被视为一个输入
将生成输入源的所有组合。
例如:::12:::a b c将产生组合(1,a)(1,b)
(1,c)(2,a)(2,b)(2,c)。这对于替换嵌套对象非常有用-
循环。
...
::argfiles
另一种写入方式-argfile1-argfile2。。。
::和:::可以混合。
请参见-a、::和--xapply。
这称为笛卡尔积。您尝试用什么语言实现它?循环中的in
将按照file2
在哈希表内部存储的顺序输出内容,而不一定是按照它们在file2中出现的顺序。它也不会处理标题行。
paste <(head -n1 file1) <(head -n1 file2); parallel printf '"%s\t%s\n"' {1} {2} \
:::: <(tail -n+2 file1) \
:::: <(tail -n+2 file2)
Var1 Var2
1 6
1 7
1 8
2 6
2 7
2 8
3 6
3 7
3 8