텍스트 파일에서 몇 줄을 복사하고 약간의 변경을 가하세요.

텍스트 파일에서 몇 줄을 복사하고 약간의 변경을 가하세요.

텍스트 파일에서 단일 범위의 줄을 복사하는 방법을 알아내려고 합니다. 범위는 파일의 고유한 줄로 시작하지만 파일의 여러 위치에 존재할 수 있는 줄로 끝납니다.

다음은 처리해야 하는 몇 가지 입력 예입니다.

상상력이 없어
따라서 이 예제 텍스트는
흔한
지루하다. 하지만 그건 사실이야
질문 보여주기
나는 그것을 위해 노력하고 있습니다.
흔한
안녕 엄마!
독특한 라인이에요.
더있다
복사해야 할 텍스트
게다가.
흔한
뒤에 문자가 와야지
복사되지 않았습니다.

복사하고 수정해야 하는 줄은 여기에 표시하기 위해 굵게 표시되어 있습니다.

내가 필요한 출력은 다음과 같습니다

상상력이 없어
따라서 이 예제 텍스트는
흔한
지루하다. 하지만 그건 사실이야
질문 보여주기
나는 그것을 위해 노력하고 있습니다.
흔한
안녕 엄마!
바뀌는 라인입니다.
그리고 여기서는 훨씬 더 달라요
복사해야 할 텍스트
게다가.
흔한
독특한 라인이에요.
더있다
복사해야 할 텍스트
게다가.
흔한
뒤에 문자가 와야지
복사되지 않았습니다.

명확성을 위해 추가 출력은 굵게 표시됩니다.

다음으로 시작하는 행 범위를 가져와야 합니다.

독특한 라인이에요

다음 줄로 끝납니다.

흔한

이 범위의 행은 원래 범위의 행 앞에 삽입되어야 합니다. 행 범위와 일치하는 복사본을 약간 수정해야 합니다.

범위를 끝내는 "공통" 줄 자체가 파일 내의 여러 위치에 나타날 수 있습니다.

나는 작동하는 스크립트를 생각해 냈지만 awk필요한 것보다 훨씬 더 복잡해 보입니다. 내 awk기술은 단순히 존재하지 않았습니다.

/This is a unique line/{flag=1}
/Common/{
    if (flag > 0) {
        n=m;
        sub("some","different",n);
        sub("unique","changed",n);
        print n "\n" $0 "\n" m;
        m=""
    };
    flag=0
};
flag{
    if (length(m) > 0) {
        m=m "\n" $0
    } else {
        m=$0
    }
}
!flag{ print }

이를 달성하는 더 깨끗하고 간결한 방법이 있습니까? 그 외에 다른 옵션도 열려 있습니다 awk. macOS에서 사용할 수 있는 표준 명령이면 됩니다.

답변1

사용ex, POSIX 지정 파일 편집기(비시각적 형태도 마찬가지 vi).

printf '%s\n' '/This is a unique line' '.,/Common/copy -' %p | ex file.txt

그러면 수정된 파일 내용이 인쇄되지만 변경 사항은 저장되지 않습니다.

변경 사항을 저장하는 명령은 다음과 같습니다.

printf '%s\n' '/This is a unique line' '.,/Common/copy -' x | ex file.txt

Awk 및 Sed와 달리 ex라인을 순차적으로 수정하는 데만 국한되지 않습니다. 대신 단순히 앞으로 이동하는 것이 아니라 전체 버퍼에서 작동합니다.

첫 번째 명령 /This is a unique line은 단지 모션 명령입니다. 가 있는 곳으로 커서를 이동시킵니다 This is a unique line.

다음 명령은 copy명령입니다. 현재 라인( .)부터 일치하는 다음 라인까지 의 주소 범위에서 작동하며 Common이를 -현재 라인( ) 이전 라인에 복사합니다.


업데이트: 수정 후 복사를 위해 먼저 시작하는 줄을 표시합니다. 복사할 첫 번째 행에는 "b"라는 레이블이 지정되고 그 앞의 행에는 "a"라는 레이블이 지정됩니다. 복사된 줄은 'a와 'b 사이에 배치되며 이 줄을 주소의 "바꾸기" 명령으로 사용할 수 있습니다. 그건 그렇고, And t는 동의어입니다.copy

printf "/Here is a unique line
kb
-ka
.,/Common/t 'a
'a+,'b-s/unique/changed/g
'a+,'b-s/some/different/g
x
" | ex file.txt

답변2

sed -e '
   /This is a unique line/,/Common/!b
   H
      /Common/!d
   g
      s/^\n//
   h
      s/unique/changed/
      s/some/different/
   G
' yourfile

설명하다

  • 먼저 범위가 아닌 행을 거부합니다.
  • 범위의 각 행에 대해 예약된 공간에 추가합니다.
  • 공통 라인이 보일 때까지 읽은 모든 라인을 삭제합니다. 이 시점에서 우리는 예약된 영역(전체 범위 + 선행 "\n"을 포함해야 함)을 검색합니다.
  • 우리는 이 선행 개행 문자를 제거하고 보존을 업데이트합니다. 이는 HBTW 명령 때문입니다 .
  • 이제 편집으로 이동합니다. 고유함 -> 변경됨, 일부 -> 다름,...
  • 예약된 공간(변경되지 않은 버전)을 패턴 공간(변경된 버전)에 추가합니다.
  • sed는 패턴 공간의 내용을 자동으로 인쇄합니다.

답변3

awk '/This is a unique line/,/Common/{
   H = H RS $0
   if ( $0 ~ /Common/ ) {
      g = H
      sub("\n","",g)
      sub("some","different",g)
      sub("unique","changed",g)
      $0 = g H
   } else { next }
}1'   inputfile

이는 sed로 번역 됩니다 awk.

awk가지고 있는 코드는 라인을 추적하기 위해 변수 플래그를 켜거나 끄는 역할을 담당합니다 . 그러나 연산자를 사용하면 awk뒤에서 똑같은 작업이 이미 수행됩니다.range,

관련 정보