2016-10-08 41 views
1

文件1:emp.txt如何根据两个文件中的匹配列找到列的值?

7839|KING|PRESIDENT||17-Nov-81|5000||10 
7698|BLAKE|MANAGER|7839|01-May-81|2850||30 
7782|CLARK|MANAGER|7839|09-Jun-81|2450||10 
7566|JONES|MANAGER|7839|02-Apr-81|2975||20 
7788|SCOTT|ANALYST|7566|19-Apr-87|3000||20 
7902|FORD|ANALYST|7566|03-Dec-81|3000||20 
7369|SMITH|CLERK|7902|17-Dec-80|800||20 
7499|ALLEN|SALESMAN|7698|20-Feb-81|1600|300|30 
7521|WARD|SALESMAN|7698|22-Feb-81|1250|500|30 
7654|MARTIN|SALESMAN|7698|28-Sep-81|1250|1400|30 

文件2:dept.txt

10|ACCOUNTING|NEW YORK 
    20|RESEARCH|DALLAS 
    30|SALES|CHICAGO 
    40|OPERATIONS|BOSTON 

我想打印输出如下:

7839|KING|PRESIDENT||17-Nov-81|5000||10|NEW YORK 
7698|BLAKE|MANAGER|7839|01-May-81|2850||30|CHICAGO 
7782|CLARK|MANAGER|7839|09-Jun-81|2450||10|NEW YORK 
7566|JONES|MANAGER|7839|02-Apr-81|2975||20|DALLAS 
7788|SCOTT|ANALYST|7566|19-Apr-87|3000||20|DALLAS 
7902|FORD|ANALYST|7566|03-Dec-81|3000||20|DALLAS 
7369|SMITH|CLERK|7902|17-Dec-80|800||20|DALLAS 
7499|ALLEN|SALESMAN|7698|20-Feb-81|1600|300|30|CHICAGO 
7521|WARD|SALESMAN|7698|22-Feb-81|1250|500|30|CHICAGO 
7654|MARTIN|SALESMAN|7698|28-Sep-81|1250|1400|30|CHICAGO 

我想下面的awk语句,但它不打印任何东西 -

awk -F'|' 'NR==FNR {val[$1]=$3; next} $8 in val {print $1,$2,$3,$4,$5,$6,$7,$8,val[$1]}' OFS="|" dept.txt emp.txt 

任何建议?

+1

没有你忘了'-F \ |'? –

+0

感谢回答,我只注意到我错过了现场分隔符,但我想与太多,但仍然没有运气... –

回答

1

的问题是有在匹配列前面两个空间。由于您使用'|'作为你的字段分隔符,然后如下第二个文件的每行分开。(使用第一行作为例子。)

10|ACCOUNTING|NEW YORK 

$1=" 10" 
$2="ACCOUNTING" 
$3="NEW YORK" 

所以你映射Accounting" 10"而非"10"。这就是为什么你没有在第二个文件中得到任何匹配。 (假设你想在第二个打印命令中使用val [$ 8]而不是val [$ 1])。

做到以下几点。这将解决您的问题。

awk -F'|' 'NR==FNR {sub(" ","",$1);val[$1]=$3; next;} $8 in val {print $1,$2 
,$3,$4,$5,$6,$7,$8,val[$8]}' OFS="|" dept.txt emp.txt 

输出:

7839|KING|PRESIDENT||17-Nov-81|5000||10|NEW YORK 
7698|BLAKE|MANAGER|7839|01-May-81|2850||30|CHICAGO 
7782|CLARK|MANAGER|7839|09-Jun-81|2450||10|NEW YORK 
7566|JONES|MANAGER|7839|02-Apr-81|2975||20|DALLAS 
7788|SCOTT|ANALYST|7566|19-Apr-87|3000||20|DALLAS 
7902|FORD|ANALYST|7566|03-Dec-81|3000||20|DALLAS 
7369|SMITH|CLERK|7902|17-Dec-80|800||20|DALLAS 
7499|ALLEN|SALESMAN|7698|20-Feb-81|1600|300|30|CHICAGO 
7521|WARD|SALESMAN|7698|22-Feb-81|1250|500|30|CHICAGO 
7654|MARTIN|SALESMAN|7698|28-Sep-81|1250|1400|30|CHICAGO 
+0

验证。看起来这是一个格式化问题,在dept.txt文件的开头部分有一些空格,但是将sub函数引入到图片中,这对我来说是一种学习。 –

+1

如果仅仅有一些简短的方式来写'打印$ 1,$ 2,$ 3,$ 4 $ 5,$ 6,$ 7 8' $用于记录与8个字段...(提示:'$ 0')。 –

0

在你的代码行,你应该叫由具有在那里你散列每个值,在你的情况下,ID列中的散列值,列8是存储常用ID为文件中的一个,你要打印的信息出。

awk -F\| 'NR==FNR {val[$1]=$3; next} {print $1, $2, $3, $4, $5, $6, $7, $8, val[$8]};' OFS="|" dept.txt emp.txt 
2

使用$NF,这是最后一个字段的值:

➜ awk ' 
    BEGIN { FS = OFS = "|" } 
    NR==FNR { location[$1] = $NF; next } 
    { print (location[$NF] ? $0 OFS location[$NF] : $0) } 
' dept.txt emp.txt 
7839|KING|PRESIDENT||17-Nov-81|5000||10|NEW YORK 
7698|BLAKE|MANAGER|7839|01-May-81|2850||30|CHICAGO 
7782|CLARK|MANAGER|7839|09-Jun-81|2450||10|NEW YORK 
7566|JONES|MANAGER|7839|02-Apr-81|2975||20|DALLAS 
7788|SCOTT|ANALYST|7566|19-Apr-87|3000||20|DALLAS 
7902|FORD|ANALYST|7566|03-Dec-81|3000||20|DALLAS 
7369|SMITH|CLERK|7902|17-Dec-80|800||20|DALLAS 
7499|ALLEN|SALESMAN|7698|20-Feb-81|1600|300|30|CHICAGO 
7521|WARD|SALESMAN|7698|22-Feb-81|1250|500|30|CHICAGO 
7654|MARTIN|SALESMAN|7698|28-Sep-81|1250|1400|30|CHICAGO 

这是假设你还是想整条生产线,无论是否系城市指数存在。如果不是,那么请更新您的问题以反映常见用例和预期输出。

+0

它在这种情况下工作正常,但它会像右外连接一样工作,比方说,如果我将从dept.txt文件中删除记录10,它将从最后一列中的位置详细信息中打印emp.txt文件中的所有记录。如果我只想加入匹配列,那么我们需要修改下面的打印语句 - awk'BEGIN {FS = OFS =“|” } NR == FNR {location [$ 1] = $ NF;下一个} $ 8位置{print $ 0,location [$ NF]}'dept.txt emp.txt 不知道如何使用三元运算符做到这一点。让我知道你的建议。 –

+1

没错。只需稍作调整即可避免必须指定公共部分('$ 0')两次,并使测试更加健壮:'print $ 0($ NF in location?OFS location [$ NF]:“”) –

相关问题