특정 문자열이 포함된 줄을 파일 맨 위로 이동하는 방법은 무엇입니까?

특정 문자열이 포함된 줄을 파일 맨 위로 이동하는 방법은 무엇입니까?

특정 문자열(예: 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 등과 같이 항상 숫자에 이중 0을 추가하므로 행을 이동할 때 숫자만 지정할 수 있으면 좋을 것입니다.

이것이 가능한가?

답변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

관련 정보