Pya*_*lli 8 command-line text-processing
我有两个文件,我想从中创建包含所有信息的第三个文件。
文件1:
a 111
b 222
c 333
d 666
e 777
Run Code Online (Sandbox Code Playgroud)
文件2:
111 x1
222 x2
333 x3
444 x4
555 x5
666 x6
777 x7
888 x8
Run Code Online (Sandbox Code Playgroud)
我想将它们组合如下:
111 x1 a
222 x2 b
333 x3 c
444 x4 0
555 x5 0
666 x6 d
777 x7 e
888 x8 0
Run Code Online (Sandbox Code Playgroud)
笔记:
文件 1 的第二列是文件 2 第一列的子集
Lil*_*loX 13
使用连接:
join -1 1 -2 2 -a1 -e0 -o'0,1.2,2.1' file2 file1
Run Code Online (Sandbox Code Playgroud)
join 命令将共享公共数据字段的两个文件的行连接起来。在这种情况下:使用 file2 的字段 1 ( -1 1)和 file1 的字段 2 ( ) 连接 file2 和-2 2file1。
输出将是:“joined field, field 2 of file2, field 1 of file1” ( -o'0,1.2,2.1'),如果缺少字段,则输入 0 ( -e0)
如果两个文件之一有更多记录,则添加它们(在本例中为 file2) ( -a1)
请参阅命令 join 的联机帮助页
join如果文件按照您的示例进行排序,该命令几乎可以满足您的需求:
join -12 -a2 file1 file2 -o2.1,2.2,1.1
Run Code Online (Sandbox Code Playgroud)
您只需要在没有匹配的行中添加零即可。您可以-e为此使用开关:
join -12 -a2 file1 file2 -o2.1,2.2,1.1 -e0
Run Code Online (Sandbox Code Playgroud)
有点awk魔法:
awk 'FNR==NR{a[$2]=$1;next}{if(a[$1]==""){a[$1]=0}; \
printf "%s%s%s%s%s\n",$1,FS,$2,FS,a[$1]}' \
file1 file2
Run Code Online (Sandbox Code Playgroud)
或者
awk 'FNR==NR{a[$2]=$1;next}{if(a[$1]==""){a[$1]=0};
print $1,$2,a[$1]}' file1 file2
Run Code Online (Sandbox Code Playgroud)
输出
111 x1 a
222 x2 b
333 x3 c
444 x4 0
555 x5 0
666 x6 d
777 x7 e
888 x8 0
Run Code Online (Sandbox Code Playgroud)
解释
FNR==NR{a[$2]=$1;next}
运行file1( FNR==NR) 并创建一个键值结构。键是 的第二列 ( $2) file1,值是 的第一列 ( $1)file1
{if(a[$1]==""){a[$1]=0};print $1,$2,a[$1]}
跑过去file2和
if(a[$1]==""){a[$1]=0}
如果第一列 ( $1) infile2中的键不存在于 中file1,我们需要一个0
print $1,$2,a[$1]
打印(使用print)的第一列和第二列file2以及具有第一列($1)的键的键值结构的值file2
或者
printf "%s%s%s%s%s\n",$1,FS,$2,FS,a[$1]}'
打印(使用printf)的第一列和第二列file2以及具有第一列 ( $1)的键的键值结构的值file2。
FS 是列之间的分隔符,取自输入文件
"%s%s%s%s%s\n"
是输出的格式
%s - 细绳
\n - 新队