처음부터 마지막까지 순차적으로 입력을 받아들이거나 출력을 뒤집도록 이 "printf" 코드를 수정하려면 어떻게 해야 합니까?

처음부터 마지막까지 순차적으로 입력을 받아들이거나 출력을 뒤집도록 이 "printf" 코드를 수정하려면 어떻게 해야 합니까?

예를 들어, 다음 코드는 다음을 수행할 수 있습니다.

[anony@mous-pc ~]$ (printf 'g?%s?m0\n' 008 006 004 002 ; printf 'wq\n') | ed -s file.txt

...안에 있는 모든 숫자를 선택하세요...

[anony@mous-pc ~]$ cat file.txt
005
003
110
069
002
008
004
245
009
007
006

...원하는 숫자(또는 다른 문자열)를 맨 위로 이동합니다.하지만 역순으로코드가 실행되었습니다...

[anony@mous-pc ~]$ cat file.txt
002
004
006
008
005
003
110
069
245
009
007

...역순을 지정하는 한 순서는 처음부터 끝까지(역순)가 됩니다. 또는... 다른 사람들은 이를 위에서 아래 형식이라고 부를 수도 있습니다. 다시 한 번, 처음부터 끝까지 구현합니다. 이런 식으로 마지막 명령을 실행해야합니다 ...

[anony@mous-pc ~]$ (printf 'g?%s?m0\n' 008 006 004 002 ; printf 'wq\n') | ed -s file.txt

하지만 처음부터 끝까지 숫자(또는 문자열)를 입력하고 처음부터 마지막까지 순서를 유지하려면 어떻게 해야 합니까?

입력 결과를 변경할 수 없는 경우 sed출력 결과를 변경하고 저장하기 전에 뒤집거나 반전할 수 있나요 file.txt?

답변1

$ perl -lne '
   /00[2468]$/ ? $h{$_} : $A[@A] = $_; }{
   print for @h{qw/008 006 004 002/}, @A;
' file.txt

일치하는 행과 일치하지 않는 행을 별도의 컨테이너에 저장합니다. 인쇄할 때가 되면 해시 %h 유형의 익명 배열에서 순서를 추출하세요.

설명하다:

  • 각 줄을 읽으면서 일치하는 줄, 즉 2, 4, 6 또는 8로 끝나는 줄이 포함되어 있는지 확인합니다. %h일치하는 행 전체가 키가 되도록 해시에 저장합니다 $h{$_}.
  • OTW, 일치하는 항목이 없으면 일치하지 않는 행을 배열 뒤쪽으로 푸시합니다 @A.
  • 파일의 끝을 본 후 %h먼저 해시 값을 인쇄합니다. 아시다시피 해시 값에 대한 액세스는 본질적으로 무작위입니다. 하지만 이것이 당신의 요구 중 하나이기 때문에 우리는 명령을 내려야 합니다. 따라서 우리는 표시되기를 원하는 순서대로 키를 나열하여 순서를 지정합니다. qw/008 006 004 002/이는 익명 배열입니다. $h{008}그러면 인쇄됩니다 $h{006}.
  • 그런 다음 array @A일치하지 않는 줄이 포함된 내용을 인쇄합니다. 양자전기역학
  • 이제 배열을 인쇄하는 순서를 바꾸면 일치하는 요소가 북쪽이 아닌 남쪽으로 이동하는 @A것을 hash slice @h{...}볼 수 있습니다.
  • 이 코드는 stdout으로만 인쇄하므로 원래 내용으로 다시 이동해야 합니다.perl '...' file.txt > /tmp/file.txt; mv /tmp/file.txt file.txt

답변2

이동하려는 순서대로 구분선 뒤에서 이동하려는 줄을 이동한 다음 구분선 뒤의 모든 줄을 문서의 시작 부분으로 이동합니다.

먼저 편집 버퍼 끝에 빈 줄을 삽입하고 다음과 같이 표시합니다 ka.

a

.
ka

버퍼의 마지막 줄을 사용하는 대신 새 줄을 구분 기호로 삽입하면 마지막 줄이 이동해야 하는 줄 중 하나일 때 복잡함을 피할 수 있습니다. 빈 줄을 이동하려면 이 특수 구분선에 고유한 텍스트를 삽입하세요 ---divider---.

그런 다음 일치하는 각 줄을 표시하려는 줄 위에서 나열하려는 순서대로 버퍼 끝으로 이동합니다.

1,'a- g/008/ m$
1,'a- g/006/ m$
1,'a- g/004/ m$
1,'a- g/002/ m$

행을 역순으로 가져오려면 버퍼 끝이 아닌 표시된 행 뒤에 각 행을 삽입하십시오. 'a위 명령 끝에 at 대신을 사용하여 $이 작업을 수행 할 수 있습니다.m

표시된 줄 뒤의 모든 줄을 버퍼의 시작 부분으로 이동하고 삽입된 구분선을 제거하여 끝냅니다.

'a+,$ m0
$ d

( 'a ddelete로 줄을 표시하는 것은 더 짧지만 자체 문서화되지만 $ d마지막 줄이 삭제할 올바른 줄인 이유를 이해해야 합니다. 이제 구분선이 버퍼링되므로 'a,$ m0후행을 사용할 수도 있습니다.)1 d

ed -svia 에 필요한 명령을 입력합니다 printf(마지막 두 명령은 버퍼의 줄 번호를 인쇄하고 무조건 편집기를 종료합니다).

{
    printf '%s\n' a '' . ka
    printf "1,'a- g/%s/ m$\n" 008 006 004 002
    printf '%s\n' "'a+,$ m0" '$ d'
    printf '%s\n' ,n Q
} | ed -s file.txt

위의 솔루션은 본질적으로 Perl이 제안한 솔루션과 동일합니다.다른 대답으로, 편집 버퍼 끝에 있는 줄은 배열 역할을 합니다 @A.

관련 정보