Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Shell 合并文件,使表1中的行对表2中的每一行重复_Shell_Unix_Join_Awk_Sed - Fatal编程技术网

Shell 合并文件,使表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]++

不确定这两个表的连接的技术术语是什么(在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]++; 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