特定の文字列を含む行をファイルの先頭に移動するには?

特定の文字列を含む行をファイルの先頭に移動するには?

特定の文字列(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を使用して、一致する行と一致しない行を格納するために2つの配列を保持します。

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

関連情報