根据逻辑对文本文件进行排序

根据逻辑对文本文件进行排序

我有 .txt 文件,每行有 1000 个字符串,文件有数百万行。客户的新要求是根据以下逻辑对该文件进行排序。提前致谢,我是 unix 新手,在论坛上找不到解决方案。

如果字符位置 6 到 11 是“CIP002”,则根据字符位置 13 到 21 进行排序 如果字符位置 6 到 11 是“CIP003”,则根据位置 20 到 28 中的字符进行排序)

排序前

00001CIP002_123456789ABCDEFJ
00002CIP002_123456790EFGHIJK
87654CIP003_ABCDEFJ123456789
87655CIP003_EFGHIJK123456790

排序后

00001CIP002_123456789ABCDEFJ
87654CIP003_ABCDEFJ123456789
00002CIP002_123456790EFGHIJK
87655CIP003_EFGHIJK123456790

答案1

这非常简单。使用 python / awk / perl / bash / 无论什么来编码 CIP{2,3} 业务逻辑,并组合一个管道。

您想要一个如下所示的输出流:

$ cat two_column.txt
123456789 00001CIP002_123456789ABCDEFJ
123456790 00002CIP002_123456790EFGHIJK
123456789 87654CIP003_ABCDEFJ123456789
123456790 87655CIP003_EFGHIJK123456790

现在以通常的方式排序,并在后处理步骤中去除该前缀。

$ cat two_column.txt | sort | awk '{print $2}'  > result.txt

答案2

awk来救援;)

gawk '$1 ~ /.{5}CIP002_.*/ {print substr($0, 13, 9)" "$0}
$1 ~ /.{5}CIP003_.*/ {print substr($0, 20, 9)" "$0}' before.txt | sort | awk '{print $2}'

它应该与gawk

说明:

  • gawk '$1 ~ /.{5}CIP002_.*/ {print substr($0, 13, 9)" "$0} $1 ~ /.{5}CIP003_.*/ {print substr($0, 20, 9)" "$0}' yourfile.txt
    • $1 ~ /.{5}CIP002_.*/过滤器符合CIP002
      • .{5}与前五个字符匹配
      • 其次是CIP002_
      • 后跟任意字符串
    • print substr($0, 13, 9)" "$0是将数据的排序部分打印到第一列:
      • substr($0, 13, 9)将行从字符 13 剪切到字符 21
      • 该指令将 打印123456789为第一列,然后是一个空格,然后是数据

输出样本:

123456789 00001CIP002_123456789ABCDEFJ
123456790 00002CIP002_123456790EFGHIJK
123456789 87654CIP003_ABCDEFJ123456789
123456790 87655CIP003_EFGHIJK123456790
  • | sort:将生成的输出重定向到sort命令的管道,该命令仅根据第一列对其进行排序。

输出样本:

123456789 00001CIP002_123456789ABCDEFJ
123456789 87654CIP003_ABCDEFJ123456789
123456790 00002CIP002_123456790EFGHIJK
123456790 87655CIP003_EFGHIJK123456790
  • | awk {print $2}:只打印数据,不带排序列

输出样本:

00001CIP002_123456789ABCDEFJ
87654CIP003_ABCDEFJ123456789
00002CIP002_123456790EFGHIJK
87655CIP003_EFGHIJK123456790

答案3

两种方法可能是:

前置排序键并在排序后删除:

<your-file awk '{
  print substr($0,6,6) == "CIP002" ? substr($0,13,9) : substr($0,20,9), $0}' |
    sort -k1,1 |
    cut -d ' ' -f 2-

或者在排序键之前插入一个标记:

<your-file perl -pe '
  substr($_, substr($_,5,6) eq "CIP002" ? 12 : 19, 0) = "|"' |
  sort -t '|' -k2,2.9 |
  tr -d '|'

(假设|输入中不会出现其他情况)。

平局是通过sort最后的比较来解决的,该比较从词法上比较整行。

相关内容