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 基于公共字段将多行转换为一行(分组依据)_Shell_Unix_Awk - Fatal编程技术网

Shell 基于公共字段将多行转换为一行(分组依据)

Shell 基于公共字段将多行转换为一行(分组依据),shell,unix,awk,Shell,Unix,Awk,我有固定长度的文件(已排序),需要根据关键字段连接多行中的字段。键字段是前两列。前3行开头有空格。实际的文件没有“空格”字,我把它放在这里是为了保持格式 输入文件 spaces2 001 111 111 Company Code 227 spaces2 001 111 111 Plan Code 012 space

我有固定长度的文件(已排序),需要根据关键字段连接多行中的字段。键字段是前两列。前3行开头有空格。实际的文件没有“空格”字,我把它放在这里是为了保持格式

输入文件

spaces2   001  111  111 Company Code         227                                
spaces2   001  111  111 Plan Code            012                                 
spaces2   001  111  111 Invoice Number       2014010                            
0000002     2  111  111 Company Code         214                                
0000002     2  111  111 Plan Code            20                                 
0000002     2  111  111 Invoice Number       3014010                            
所需输出:

spaces2   001  111  111 Company Code         227-12-2014010                                
0000002     2  111  111 Company Code         214-20-3014010                                

有人能建议怎么做吗。

试试这样的方法:

$ cat file
      2   001  111  111 Company Code         227
      2   001  111  111 Plan Code            012
      2   001  111  111 Invoice Number       2014010
0000002     2  111  111 Company Code         214
0000002     2  111  111 Plan Code            20
0000002     2  111  111 Invoice Number       3014010
请注意,
awk
中的数组是关联的,因此输出顺序是随机的。如果订单很重要,则需要使用附加代码来处理

如果订单对您至关重要,则您可以执行以下操作:

awk '($1,$2) in seen {
    lines[i] = lines[i]"-"$NF; 
    next
}
{
    gsub(/ *$/,""); 
    seen[$1,$2]++; 
    lines[++i] = $0
}
END {
    for(line = 1; line <= length(lines); line++) {
        print lines[line]
    }
}' file
awk'(1美元,2美元){
行[i]=行[i]“-”$NF;
下一个
}
{
gsub(/*$/,“”);
见[$1,$2]++;
行[++i]=$0
}
结束{

对于(line=1;awk中的行字符串连接可以像
$1“-“$2”-”$3
一样简单。你从@n0741337到达那里有困难吗?我找不到我想要的东西,而Jaypal的逻辑对我的情况没有帮助。回答得很好我的朋友注意,OP说文件有“固定长度”行。这意味着每行都有尾随空格。在这种情况下,输出会有所不同。此外,如果删除尾随行,然后连接,最好使用
printf
保持长度不变。好的观点@Kent。我添加了一个lazy
gsub
来删除尾随空格。@jaypal,我将实现您的解决方案,我将被要求保留尾随空格输出中的顺序。Thanks@user3353722我添加了另一个解决方案来保持数据的有序。但是,它希望您的输入数据的顺序相同。
awk '($1,$2) in seen {
    lines[i] = lines[i]"-"$NF; 
    next
}
{
    gsub(/ *$/,""); 
    seen[$1,$2]++; 
    lines[++i] = $0
}
END {
    for(line = 1; line <= length(lines); line++) {
        print lines[line]
    }
}' file