如何将包含特定字符串的行移至文件顶部?

如何将包含特定字符串的行移至文件顶部?

如何将包含特定字符串(即 005 和 007)的行移至目标文件的顶部?

目标文件内容:

XXX_008
XXX_001
XXX_002
XXX_009
XXX_003
XXX_006
XXX_005 ----> located here
XXX_007 ----> and here
XXX_004

如何将行移至XXX_005顶部XXX_007?保留其余文件的顺序?就像这样:

XXX_005 ----> now here
XXX_007 ----> and here
XXX_008
XXX_001
XXX_002
XXX_009
XXX_003
XXX_006
XXX_004

其余的都保持原来的顺序。

...在移动行时能够仅指定数字会很好,因为我总是使用双零填充数字,例如any-name_001、any-name_002等。

这有可能吗?

答案1

尝试:

<file gawk '/_005/,/_007/ {
  top[i++]=$0
  next
}
{
  botom[j++]=$0
}
END {
  for(k in top)
    print top[k]
  for(k in botom)
    print botom[k]
}'

答案2

首先cat是具有匹配模式的行,然后是具有恢复匹配模式的行:

cat <(grep -x 'XXX_00[57]' infile) <(grep -xv 'XXX_00[57]' infile)

笔记:正如您提到的以上述特定模式移动行,那么您可能需要从-x用于在整行中匹配该模式的命令中删除选项。

答案3

随着GNU sed它的扩展正则表达式引擎的启用,我们可以解决这个问题。保留空间包含所有需要向北移动的行,而模式空间包含不匹配的行。

$ sed -Ee '
    /_005|_007/{
      /\n/!{
        H;$!d;g;s/.//;b
      }
      G
      s/(.*\n.*)(\n.*)(\n\n.*)/\1\3\2/
      h;s/.*\n(\n)/\1/
      x;s/\n\n.*//
      $bend
      s/^/\n/;D
    }
    $bend
    N;s/^/\n/;D
    :end
    x;G;s/.//
' input.txt

使用 perl,我们维护两个数组来存储匹配的和不匹配的行:

$ perl -ne 'push @{/_005|_007/ ? \@A : \@B}, $_}{print @A, @B' input.txt

相关内容