Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.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
Unix 使用awk和sort按ID字段对表进行排序_Unix_Sorting_Awk - Fatal编程技术网

Unix 使用awk和sort按ID字段对表进行排序

Unix 使用awk和sort按ID字段对表进行排序,unix,sorting,awk,Unix,Sorting,Awk,我正在学习Unix,我想对这个表进行排序: Name:Alice,ID:2368,Hometown:columbus,bithday:03/11/1988 Name:Ted,ID:2368,Hometown:Portland,bithday:06-11-1992 Name:Mark,ID:2218,Hometown:Palo Alto,bithday:04-23-1984 Name:Xiao,ID:2571,hometown:Carson,bithday:07/06/1975 Name:Rain

我正在学习Unix,我想对这个表进行排序:

Name:Alice,ID:2368,Hometown:columbus,bithday:03/11/1988
Name:Ted,ID:2368,Hometown:Portland,bithday:06-11-1992
Name:Mark,ID:2218,Hometown:Palo Alto,bithday:04-23-1984
Name:Xiao,ID:2571,hometown:Carson,bithday:07/06/1975
Name:Rain,ID:0264,hometown:little stone,bithday:11-09-1982
Name:Susan,ID:1261,Hometown:Menlo park,bithday:12-13-1989
Name:Zack,ID:1594,Hometown:columbus,bithday:02-04-1984
并将其格式化如下:

Rain,0264,little stone,11-09-1982
Susan,1261,Menlo park,12-13-1989
Zack,1594,columbus,02-04-1984
Mark,2218,Palo Alto,04-23-1984
Alice,2368,columbus,03-11-1988
Ted,2368,Portland,06-11-1992
Xiao,2571,Carson,07-06-1975
我想过滤掉键值对(key:value)中的键,然后使用awk和sort按ID排序


我将使用哪些命令来执行此操作?

我发现的最简单的方法是使用
awk
重新格式化输出,并附加一个
排序将使用的新列,然后再次使用
awk
隐藏该列

$ cat test.dat
Name:Alice,ID:2368,Hometown:columbus,bithday:03/11/1988
Name:Ted,ID:2368,Hometown:Portland,bithday:06-11-1992
Name:Mark,ID:2218,Hometown:Palo Alto,bithday:04-23-1984
Name:Xiao,ID:2571,hometown:Carson,bithday:07/06/1975
Name:Rain,ID:0264,hometown:little stone,bithday:11-09-1982
Name:Susan,ID:1261,Hometown:Menlo park,bithday:12-13-1989
Name:Zack,ID:1594,Hometown:columbus,bithday:02-04-1984

$ cat test.dat| awk -F, '{ gsub(/[a-zA-Z]+:/, ""); print $2,$0; }' | sort | awk '{ $1=""; print; }'
 Rain,0264,little stone,11-09-1982
 Susan,1261,Menlo park,12-13-1989
 Zack,1594,columbus,02-04-1984
 Mark,2218,Palo Alto,04-23-1984
 Alice,2368,columbus,03/11/1988
 Ted,2368,Portland,06-11-1992
 Xiao,2571,Carson,07/06/1975
-F
用于指定分隔符(此处为
)。然后我们想删除列名(即任何字母后跟
),最后显示ID列和整个重写行。 然后我们使用
sort
,默认情况下假定排序键是第一列,然后再次使用
awk
仅显示每行的第二部分


编辑:考虑到城市中的空间,awk存在输出问题。为了简单起见,我只是重新分配了第一个变量(您希望隐藏的列)并打印整行。

必须有awk吗?如果没有:

  • 使用
    Vim
    删除带有
    :%s/[a-z]*:///gi
  • 使用sort进行排序:
    sort-t,-k2文件
  • 如果AWK是必须的,那么我会想,在不丢失密钥的情况下进行排序-但是@Aif给出的答案也很好


    编辑:由于@Aif的正则表达式和@Ghoti的评论,改进了。现在,用于替换的Vim命令使用regex和键大小写以及文本“matters not”,正如尤达大师所说。

    我花了一段时间才弄清楚,直到我最终发现输入数据中的“birth”拼写错误

    您可以全力以赴,将数据解析为实际数据:

    awk -F, '
      BEGIN {
        fmt="%s,%s,%s,%s\n";
      }
    
      {
        for (i=1;i<=NF;i++) {           # walk through the fields...
          split($i,a,":");              # split each one at the colon, save to array
          v[tolower(a[1])]=a[2];        # need tolower() as "Hometown" is inconsistent
        }
        split(v["bithday"],b,/[-\/]/);  # regex here handles your inconsistent divider
        v["bithday"]=sprintf("%s-%s-%s",b[3],b[2],b[1]);
        printf(fmt,v["name"],v["id"],v["hometown"],v["bithday"]);
      }
    ' input.txt | sort -t, -k2
    
    这将产生相同的结果,但代码更少。如果你需要用你的输入数据做更多有趣的事情,那么当然,awk是一个不错的选择


    哦,我的
    sed
    来自FreeBSD,所以它使用
    -E
    选项来获取ERE。如果您使用的是Linux或其他GNU-sed提供商,您可能可以在根据需要格式化后(我知道您已经格式化了)用
    -r
    替换
    -E
    ,您可以通过管道将数据传输到
    排序-t,-k2
    按第二列排序

    如果您实际上还没有,我认为最简单的方法之一是
    sed的//[:alnum:]*://g'

    所以整个命令都是

    sed 's/[[:alnum:]]*://g' table.csv | sort -t, -k2
    

    这里有一种使用GNU awk的方法:

    awk 'BEGIN { FS="[,:]"; OFS="," } { for (i=2; i<=NF; i+=2) printf (i!=NF) ? $i OFS : $i ORS | "sort -t, -nk2" }' file.txt
    
    就这么简单:

    awk -F: '{gsub(/,[^:]*:/,",");print $2}' You_file| sort -t, -k 2,2n
    
    测试如下:

    > cat temp
    Name:Alice,ID:2368,Hometown:columbus,bithday:03/11/1988
    Name:Ted,ID:2368,Hometown:Portland,bithday:06-11-1992
    Name:Mark,ID:2218,Hometown:Palo Alto,bithday:04-23-1984
    Name:Xiao,ID:2571,hometown:Carson,bithday:07/06/1975
    Name:Rain,ID:0264,hometown:little stone,bithday:11-09-1982
    Name:Susan,ID:1261,Hometown:Menlo park,bithday:12-13-1989
    Name:Zack,ID:1594,Hometown:columbus,bithday:02-04-1984
    >
    
    现在执行:

    > awk -F: '{gsub(/,[^:]*:/,",");print $2}' temp | sort -t, -k 2,2n
    Rain,0264,little stone,11-09-1982
    Susan,1261,Menlo park,12-13-1989
    Zack,1594,columbus,02-04-1984
    Mark,2218,Palo Alto,04-23-1984
    Alice,2368,columbus,03/11/1988
    Ted,2368,Portland,06-11-1992
    Xiao,2571,Carson,07/06/1975
    

    使用grep查找值,粘贴以重新组合行,当然还有排序:

    grep -oP '(?<=:).*?(,|$)' filename | paste -d "" - - - - | sort -n -t, -k2
    

    grep-oP'(?只需将FS和OFS设置为您头脑中的内容,打印您想要的字段,然后排序:

    $ awk -F'[:,]' -v OFS=, '{print $2,$4,$6,$8}' file | sort -t, -k2n
    Rain,0264,little stone,11-09-1982
    Susan,1261,Menlo park,12-13-1989
    Zack,1594,columbus,02-04-1984
    Mark,2218,Palo Alto,04-23-1984
    Alice,2368,columbus,03/11/1988
    Ted,2368,Portland,06-11-1992
    Xiao,2571,Carson,07/06/1975
    

    cat temp.txt | awk-F“,|:“{print$2”,“$4”,“$6}”sort-t,-k2n

    (1)您可以使keyname的大小写与vi命令
    无关:将ic
    设置为IgnoreCase。以及(2)这对于一次性操作很好,但无法轻松地自动化vim命令。最后,(3)您的“使用awk排序”链接实际上是用于GAWK,而不是awk。如果OP没有提到他的平台,那么一个好的答案将是非教派的,并且在任何地方都有效,而不仅仅是在你最喜欢的平台上。Ad Vim命令:(1)它区分大小写,因此我在@Aif的答案中标记了它(2)非常好的正则表达式(这里的第一个)很可能被用于区分大小写,这是一个没有实际意义的观点。广告“我的链接”,它涵盖了Gnu Awk和Awk,向下滚动它所指向的页面,亲自查看:“标准Awk”部分。然而,我发现GAWK的
    asorti()
    值得注意的是,因为Awk答案已经存在,所以它有什么问题吗?请解释一下这比@Aif的答案好吗?好吧,aifs的答案有3个管道和4个不同的命令,代码太多了。但是这里只有一个管道和两个命令。您还没有选择答案,所以答案是正确的ovided显然不适合你。你能描述一下没有涵盖的内容吗?无用的使用cat,
    awk…temp.txt
    也同样有效,并节省了一个(可能会失速)管道。
    grep -oP '(?<=:).*?(,|$)' filename | paste -d "" - - - - | sort -n -t, -k2
    
    $ awk -F'[:,]' -v OFS=, '{print $2,$4,$6,$8}' file | sort -t, -k2n
    Rain,0264,little stone,11-09-1982
    Susan,1261,Menlo park,12-13-1989
    Zack,1594,columbus,02-04-1984
    Mark,2218,Palo Alto,04-23-1984
    Alice,2368,columbus,03/11/1988
    Ted,2368,Portland,06-11-1992
    Xiao,2571,Carson,07/06/1975