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
unix中两个文件的左外联接_Unix_Join - Fatal编程技术网

unix中两个文件的左外联接

unix中两个文件的左外联接,unix,join,Unix,Join,我需要连接两个字段上的两个文件。但是,我应该检索文件1中的所有值,即使连接失败,就像左外部连接一样 文件1: 01|a|jack|d 02|b|ron|c 03|d|tom|e 文件2: 01|a|nemesis|f 02|b|brave|d 04|d|gorr|h 输出: 01|a|jack|d|nemesis|f 02|b|ron|c|brave|d 03|d|tom|e|| 它是join-t'|'file1 file2-a1 使用的选项: t:分隔符。 a:决定必须从中打印未成对行的

我需要连接两个字段上的两个文件。但是,我应该检索文件1中的所有值,即使连接失败,就像左外部连接一样

文件1:

01|a|jack|d
02|b|ron|c
03|d|tom|e
文件2:

01|a|nemesis|f
02|b|brave|d
04|d|gorr|h
输出:

01|a|jack|d|nemesis|f
02|b|ron|c|brave|d
03|d|tom|e||

它是
join-t'|'file1 file2-a1

使用的选项:

t:分隔符。
a:决定必须从中打印未成对行的文件编号

join-t'|'file1 file2-a2
将执行一个右外部联接

样本运行

   [aman@aman test]$ cat f1  
    01|a|jack|d

    02|b|ron|c

    03|d|tom|e
    [aman@aman test]$ cat f2
    01|a|nemesis|f

    02|b|brave|d

    04|d|gorr|h
    [aman@aman test]$ join -t '|'  f1 f2 -a1
    01|a|jack|d|a|nemesis|f

    02|b|ron|c|b|brave|d

    03|d|tom|e

要准确地回答问题,比前面的答案要复杂一点,需要这样做:

sed 's/|/:/2' file1 | sort -t: >file1.tmp
sed 's/|/:/2' file2 | sort -t: >file2.tmp
join -t':' file1.tmp file2.tmp -a1 -e'|' -o'0,1.2,2.2' | tr ':' '|'
Unix join只能在单个字段上进行联接AFAIK,因此您必须使用使用不同分隔符的文件来“联接两个字段上的两个文件”,在本例中是前两个字段。我将使用冒号,但是,如果任何输入中存在,则需要使用其他输入,例如制表符可能是更好的生产使用选择。我还在新的复合字段中对输出重新排序,
sort-t:
,对于示例输入文件来说,这没有什么区别,但对于真实世界的数据来说会有所不同
sed的/|/:/2'
在文件中的每一行用冒号替换管道的第二个匹配项

file1.tmp

01|a:jack|d
02|b:ron|c
03|d:tom|e
file2.tmp

01|a:nemesis|f
02|b:brave|d
04|d:gorr|h
现在,我们使用由
tr
过滤的
join
输出和一些更高级的选项:

  • -t':'
    指定临时冒号分隔符
  • -a1
    左外连接
  • -e'|'
    指定失败连接的替换字符串,基本上是最终输出分隔符N-1倍,其中N是连接到file2.tmp中冒号右侧的管道分隔字段数。在本例中,N=2,因此为一个管道字符
  • -o'0,1.2,2.2'
    指定输出格式:
    • 0
      join字段
    • 1.2
      file1.tmp的字段2,即冒号右边的所有内容
    • 2.2
      file2.tmp的字段2
  • tr':“|”
    最后,我们将冒号转换回管道以获得最终输出
现在,输出与问题示例输出完全匹配,而上一个答案没有:

01|a|jack|d|nemesis|f
02|b|ron|c|brave|d
03|d|tom|e||

我最近遇到了一个非常简单的输入文件的问题,只有一个字段,因此没有考虑分隔符

cat file1 > k1
cat file2 >> k1
sort k1 | uniq -c | grep "^.*1 "  
will give you lines that occur in only 1 file

这是一个特例,它可能不适用于或无法与此处发布的上述技术进行比较,但如果它对正在寻找左外连接的人有用(即,仅适用于不匹配的情况)。对“^.*2”进行灰显将得到匹配的案例。如果您有一个多字段文件(更常见的情况),但您只关心一个联接字段,那么您可以使用Awk创建一个只包含密钥的文件(每个文件),然后按上述方式处理。

没错,您的输出与他的输出相匹配。案件结案。祝大家好运。@Sheller。不完全是。在记录的末尾有一个丢失的管道,没有idm帖子中提到的匹配项。尽管如此,我还是认为这是一种策略,可以帮助大多数人克服寻找Linux外部连接函数的困难。经过深思熟虑的响应,以及对每个细节的出色解释。