sort命令用于对以特定单词开头的某些行进行排序

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sort命令用于对以特定单词开头的某些行进行排序相关的知识,希望对你有一定的参考价值。

我想根据第二列对文件进行排序,但我也想只排序以“@SQ”开头的行,这意味着尚未排序的行必须保持与它们最初相同的位置。

sort -k 2,2 filename

输入:

@HD     VN:1.0  SO:unsorted
@SQ     SN:chr11 LN:197195432
@SQ     SN:chr8 LN:181748087
@SQ     SN:chr6 LN:181741298
@SQ     SN:chr5 LN:111089233
@PL     ID:Me   RF:091284293

期望的输出:

@HD     VN:1.0  SO:unsorted
@SQ     SN:chr5 LN:111089233
@SQ     SN:chr6 LN:181741298
@SQ     SN:chr8 LN:181748087
@SQ     SN:chr11 LN:197195432
@PL     ID:Me   RF:091284293
答案

您可以通过读取两个不同的文件描述符并将排序的行替换为最终输出中的未排序行来执行您需要执行的操作。基本上,你可以利用'@SQ'的版本排序功能,例如sort -V,从grep '^@SQ' <filename.txt | sort -V 开始隔离和排序行。

stdin

然后,您可以通过读取第二个文件描述符逐行读取原始文件,从而可以读取while read -r line <&3; do ... read -r sorted ... done 3<"filename.txt" 上面排序行的输出,例如:低于FD 3读数,

read

(请注意,如果您的-r版本未提供grep '^@SQ' <filename.txt | sort -V | while read -r line <&3; do if [ "${line%% *}" = '@SQ' ]; then ## line begins with '@SQ' read -r sorted echo "$sorted" else echo "$line" fi done 3<"filename.txt" 选项,请将其删除)

将这两个部分组合在一起,您可以:

dat/sortdata.txt

我将未分类的文件存储在$ grep '^@SQ' <dat/sortdata.txt | sort -V | > while read -r line <&3; do > if [ "${line%% *}" = '@SQ' ]; then ## line begins with '@SQ' > read -r sorted > echo "$sorted" > else > echo "$line" > fi > done 3<"dat/sortdata.txt" @HD VN:1.0 SO:unsorted @SQ SN:chr5 LN:111089233 @SQ SN:chr6 LN:181741298 @SQ SN:chr8 LN:181748087 @SQ SN:chr11 LN:197195432 @PL ID:Me RF:091284293 中的位置。您可以获得所需的输出:

示例使用/输出

#!/usr/bin/python3
from natsort import natsorted
import re

insq = False
sq = []
r = re.compile( r"^@SQ")
with open( "franchini", "r" ) as f:
  for line in f:
    if not r.match( line ):
      if insq:
        for i in  natsorted(sq):
          print(i)
      print( line.strip() )
      insq = False
    else:
      sq.append( line.strip() )
      insq = True

如果您愿意,可以通过在子shell中执行上述操作并将输出重定向到文件来将输出重定向到单独的文件。仔细看看,如果您有任何其他问题,请告诉我。

另一答案

我还在学习python,所以我不会声称它很漂亮或有效,但它确实有效。

./fran.py
@HD     VN:1.0  SO:unsorted
@SQ     SN:chr5 LN:111089233
@SQ     SN:chr6 LN:181741298
@SQ     SN:chr8 LN:181748087
@SQ     SN:chr11 LN:197195432
@PL     ID:Me   RF:091284293

这保存为fran.py,您在franchini中的样本数据给出以下结果:

import re, sys

with open(sys.argv[1], 'r') as f:
    lines = f.read().splitlines()
    sq_lines = []
    for l in lines:
        if l.startswith('@SQ'):
            sq_lines.append(l)
        else:
            if sq_lines:
                processed = sorted(sq_lines, key=lambda l: int(re.split(r'(s+)', l)[2][6:]))
                print('
'.join(i for i in processed))
            print(l)
另一答案

Potkhon Solyuion:

sort_sq_lines.py脚本:

python sort_sq_lines.py filename

用法:

@HD     VN:1.0  SO:unsorted
@SQ     SN:chr5 LN:111089233
@SQ     SN:chr6 LN:181741298
@SQ     SN:chr8 LN:181748087
@SQ     SN:chr11 LN:197195432
@PL     ID:Me   RF:091284293

输出:

qazxswpoi

以上是关于sort命令用于对以特定单词开头的某些行进行排序的主要内容,如果未能解决你的问题,请参考以下文章

linux命令之----sort命令用于将文本文件内容加以排序

有一个js数组,已排序,现在需要移动某些元素到特定的位置,这种实现

Linux:cut、sort都是针对列操作,有没有对行操作的命令?

文件处理工具:wc,cut,sort,uniq

sort 文本排序

Linux基础:sort命令总结