如何使用linux shell选择文件中不同列中的内容?

如何使用linux shell选择文件中不同列中的内容?,linux,awk,Linux,Awk,我有一份档案。这个文件大约有3000行 我选了四行。内容如下: user=bio-wangxf group=bio-jinwf etime=1556506215 start=1556506216 unique_node_count=1 end=1556524815 Exit_status=0 user=bio-wangxf group=bio-jinwf jobname=cellranger start=1556506216 end=1556555583 Exit_status=0 resour

我有一份档案。这个文件大约有3000行

我选了四行。内容如下:

user=bio-wangxf group=bio-jinwf etime=1556506215 start=1556506216 unique_node_count=1 end=1556524815 Exit_status=0
user=bio-wangxf group=bio-jinwf jobname=cellranger start=1556506216 end=1556555583 Exit_status=0 resources_used.cput=338425
user=maad-inspur01 group=maad-huangsd jobname=2d-1d9-4.3-1152-RK2 queue=cal-l start=1554626044 exec_host=cu017/0-23 end=1554626044
user=maad-inspur01 group=maad-huangsd jobname=testmatlab queue=cal-l ctime=1554632326 qtime=1554632326 etime=1554632326 start=1554632328 owner=maad-inspur01@ln01 exec_host=cu191/0-11 Resource_List.nodect=1 Resource_List.nodes=1:ppn=12 session=15549 unique_node_count=1 end=1554643410 Exit_status=0 resources_used.cput=7102 resources_used.mem=31315760kb resources_used.vmem=96803568kb resources_used.walltime=03:04:42
user=iese-liul group=iese-zhengchm jobname=ssh queue=fat ctime=1555483302 qtime=1555483302 etime=1555483302 start=1555489505 owner=iese-liul@ln04 exec_host=fat02/0-17,126-142 Resource_List.neednodes=1:ppn=35 Resource_List.nodect=1 Resource_List.nodes=1:ppn=35 Resource_List.walltime=72:00:00 session=31961 total_execution_slots=35 unique_node_count=1 end=1555498389 Exit_status=0 resources_used.cput=38523 
现在我要选择用户、组、开始和结束

正确的结果应如下所示:

user=bio-wangxf group=bio-jinwf start=1556506216 end=1556524815
user=bio-wangxf group=bio-jinwf start=1556506216 end=1556555583
user=maad-inspur01 group=maad-huangsd start=1554626044 end=1554626044
user=maad-inspur01 group=maad-huangsd start=1554632328 end=1554643410
user=iese-liul group=iese-zhengchm start=1555489505 end=1555498389
因为每行有不同的列数,所以我不能使用awk来选择

我试过:

awk '{if($15~/end/) print $1" "$2" "$4" "$15; else if($18~/end/) print $1" "$2" "$8" "$18}' filename
我不能得到正确的结果。缺少某些行,因为“开始”和“结束”不在固定列中

谁能帮我?

您仍然可以使用awk:

$ awk '{
    for(i=1;i<=NF;i++)                       # loop fields
        if($i~/^(user|group|start|end)=/)    # look for keyword
            b=b (b==""?"":OFS) $i            # buffer matching field
    print b                                  # print buffer
    b=""                                     # reset and repeat
}' file

字段将按原始顺序输出。

请尝试以下操作:

awk '
BEGIN {f["user"] = f["group"] = f["start"] = f["end"] = 1}
{for (i=1; i<=NF; i++) {
    split($i, a, "=")
    if (f[a[1]]) printf("%s ", $i)
 }
print ""
}' filename
awk'
开始{f[“用户”]=f[“组”]=f[“开始”]=f[“结束”]=1}

{for(i=1;i当您有一个包含记录/行的文件,这些记录/行由
key1=value1\u FS\u key2=value2\u FS\u key3=value3…
形式的键值对组成,
\u FS\u
是字段分隔符(分隔符),我通常会将所有键值对存储在一个数组中,在该数组中可以使用键查找值或感兴趣的对象。在这种情况下,它是完整的键值组合

在awk中,这类似于:

awk '{for(i=1;i<=NF;++i) if(match($i,"=")) a[substr($i,1,RSTART-1)]=$i}
     { print a["user"],a["group"],a["start"],a["end"] }
     { delete a }' file
这可能不是你想要的,也许你想拥有类似的东西

user=bio-wangxf group=NA start=1556506216 end=1556555583
这可以通过使用一个简单的函数来完成

awk 'function lookup(key) { return (key in a ? a[key] : key"=NA") }
     {for(i=1;i<=NF;++i) if(match($i,"=")) a[substr($i,1,RSTART-1)]=$i}
     { print lookup("user"),lookup("group"),lookup("start"),lookup("end") }
     { delete a }' file
awk'函数查找(key){return(a中的key?a[key]:key“=NA”)}

{for(i=1;i如果您可以使用perl。请检查以下解决方案:

perl -lane 'for(@F){$a.=" ".$_ if(/user=|start=|end=|group=/)}print $a;undef $a' your_file

是的,这大概是最有效的方法。我考虑了
printf j?”%s:“%s”,“I;print”;j=0
,但这是不必要的独立打印每个匹配字段。@DavidC.Rankin谢谢。我首先用
printf
和分隔符在角落里画了自己,但这就是出路。我仍然没有喝过我的晨茶……我一直都有这样的事
:)
b=b(b==“”?“”:“”)$i,这行是什么意思?我会将
(b==“”?“”:“”)更新为
(b==“”?“”:OFS)
。这允许以
FS=OFS=“;”
为例灵活更改字段分隔符。
awk 'function lookup(key) { return (key in a ? a[key] : key"=NA") }
     {for(i=1;i<=NF;++i) if(match($i,"=")) a[substr($i,1,RSTART-1)]=$i}
     { print lookup("user"),lookup("group"),lookup("start"),lookup("end") }
     { delete a }' file
perl -lane 'for(@F){$a.=" ".$_ if(/user=|start=|end=|group=/)}print $a;undef $a' your_file