按公共列标题加入2个文件(不带awk / sed)

时间:2014-10-09 15:13:13

标签: linux unix join text-processing gnu-coreutils

基本上我想从file2获取所有记录,但过滤掉标题不会出现在file1

中的列

示例

文件1

Name Location

file2的

Name Phone_Number Location Email
Jim  032131       xyz      xyz@qqq.com
Tim  037903       zzz      zzz@qqq.com
Pimp 039141       xxz      xxz@qqq.com

输出

Name Location
Jim  xyz
Tim  zzz
Pimp xxz

有没有办法在没有awksed但仍然使用coreutils工具的情况下执行此操作?我已尝试使用join进行此操作,但无法使其正常运行。

2 个答案:

答案 0 :(得分:2)

ALL_COLUMNS=$(head -n1 file2)
for COLUMN in $(head -n1 file1); do
    JOIN_FORMAT+="2.$(( $(echo ${ALL_COLUMNS%%$COLUMN*} | wc -w)+1 )),"
done
join -a2 -o ${JOIN_FORMAT%?} /dev/null file2

说明:

ALL_COLUMNS=$(head -n1 file2)

它保存所有列名称以过滤下一个


for COLUMN in $(head -n1 file1); do
    JOIN_FORMAT+="2.$(( $(echo ${ALL_COLUMNS%%$COLUMN*} | wc -w)+1 )),"
done

对于file1中的每一列,我们会在file2中查找具有相同名称的列的位置,并以JOIN_FORMAT <的方式将其附加到"2.<number_of_column>," / p>


join -a2 -o ${JOIN_FORMAT%?} /dev/null file2

我们完成选项字符串(2.1,2.3,)后,我们将其传递给join,删除最后一个,

join从提供的第二个文件(-a2 -> file2)打印不可用的行,但仅打印-o选项中指定的列。

答案 1 :(得分:1)

效率不高,但适用于您的示例:

#!/bin/bash

read -r -a cols < file1
echo "${cols[@]}"

read -r -a header < <(head -n1 file2)
keep=()
for (( i=0; i<${#header}; i++ )) ; do 
    for c in "${cols[@]}" ; do
        if [[ ${header[i]} == "$c" ]] ; then
            keep+=($i)
        fi
    done
done

while read -r -a data ; do
    for idx in ${keep[@]} ; do
        printf '%s ' "${data[idx]}"
    done
    printf '\n'
done < <(tail -n+2 file2)

使用的工具:headtail。但它们并不重要。当然还有bash