Unix如何根据特定匹配对整行进行排序

时间:2016-05-31 10:13:06

标签: bash sorting unix awk

我有一个像这样的文件

$> cat testfile.txt
abc_xyz_2a      foo
dft_pqr_abc_5c  bar
pqr_ijk_1a      alpha
efg_5b          beta
ijk_pqr_5a      gamma
pqr_ijk_1b      alpha

我想根据第一列的最后一个值排序行,在最后一个下划线_之后,如1a2a5a5b 5c

所以这是我的预期输出。

pqr_ijk_1a      alpha
pqr_ijk_1b      alpha
abc_xyz_2a      foo
ijk_pqr_5a      gamma
efg_5b          beta
dft_pqr_abc_5c  bar

有人可以建议一种方法来实现预期的产出吗?

  

我尝试了什么

我尝试在第一列的最后一个下划线之后提取部分并进行排序,但这只会打印这些关键字,而不是整行。

$> awk '{print $1}' testfile.txt|rev|awk -F_ '{print $1}'|rev|sort
1a
2a
5a
5b
5c

我想有可能有办法以某种方式保持/记录行数并根据它输出?我在awk中使用NR尝试了一些点击和试用失败。

编辑:在以1b结尾的文件中添加了一行来处理另一个案例。根据它改变了预期的产出。

3 个答案:

答案 0 :(得分:3)

只需删除所需的列,对其进行排序,然后再将其删除。

$ cat data
abc_xyz_2a      foo
dft_pqr_abc_5c  bar
pqr_ijk_1a      alpha
efg_5b          beta
ijk_pqr_5a      gamma


$ awk '{print substr($1, length($1)-1, 1), substr($1, length($1)), $1, $2}' data | sort -n -k1,2 | awk '{print $3,$4}'
pqr_ijk_1a alpha
abc_xyz_2a foo
ijk_pqr_5a gamma
efg_5b beta
dft_pqr_abc_5c bar

以下是管道的每一步都会发生的事情:

$ awk '{print substr($1, length($1)-1, 1), substr($1, length($1)), $1, $2}' data
2 a abc_xyz_2a foo
5 c dft_pqr_abc_5c bar
1 a pqr_ijk_1a alpha
5 b efg_5b beta
5 a ijk_pqr_5a gamma

$ awk '{print substr($1, length($1)-1, 1), substr($1, length($1)), $1, $2}' data | sort -n -k1,2
1 a pqr_ijk_1a alpha
2 a abc_xyz_2a foo
5 a ijk_pqr_5a gamma
5 b efg_5b beta
5 c dft_pqr_abc_5c bar

答案 1 :(得分:2)

如果您有gnu-awk,那么您可以使用PROCINFO方式对数组进行排序:

awk 'BEGIN{PROCINFO["sorted_in"] = "@ind_num_asc"} {
   n=split($1, a, "_")
   data[a[n]]=$0
}
END {
   for (i in data)
      print data[i]
}' file

pqr_ijk_1a      alpha
abc_xyz_2a      foo
ijk_pqr_5a      gamma
efg_5b          beta
dft_pqr_abc_5c  bar

否则您可以使用awk-sort-cut管道:

awk '{n=split($1, a, "_"); print $0 "\0" a[n]}' file | sort -t '\0' -k2 | cut -d $'\0' -f1

pqr_ijk_1a      alpha
abc_xyz_2a      foo
ijk_pqr_5a      gamma
efg_5b          beta
dft_pqr_abc_5c  bar

答案 2 :(得分:-1)

你可以尝试下面更简单直接的命令。

 rev   test.txt | sort  -k2 | rev


pqr_ijk_1a      alpha
abc_xyz_2a      foo
ijk_pqr_5a      gamma
efg_5b          beta
dft_pqr_abc_5c  bar