![텍스트 파일에서 몇 줄을 복사하고 약간의 변경을 가하세요.](https://linux55.com/image/111770/%ED%85%8D%EC%8A%A4%ED%8A%B8%20%ED%8C%8C%EC%9D%BC%EC%97%90%EC%84%9C%20%EB%AA%87%20%EC%A4%84%EC%9D%84%20%EB%B3%B5%EC%82%AC%ED%95%98%EA%B3%A0%20%EC%95%BD%EA%B0%84%EC%9D%98%20%EB%B3%80%EA%B2%BD%EC%9D%84%20%EA%B0%80%ED%95%98%EC%84%B8%EC%9A%94..png)
텍스트 파일에서 단일 범위의 줄을 복사하는 방법을 알아내려고 합니다. 범위는 파일의 고유한 줄로 시작하지만 파일의 여러 위치에 존재할 수 있는 줄로 끝납니다.
다음은 처리해야 하는 몇 가지 입력 예입니다.
상상력이 없어 따라서 이 예제 텍스트는 흔한 지루하다. 하지만 그건 사실이야 질문 보여주기 나는 그것을 위해 노력하고 있습니다. 흔한 안녕 엄마! 독특한 라인이에요. 더있다 복사해야 할 텍스트 게다가. 흔한 뒤에 문자가 와야지 복사되지 않았습니다.
복사하고 수정해야 하는 줄은 여기에 표시하기 위해 굵게 표시되어 있습니다.
내가 필요한 출력은 다음과 같습니다
상상력이 없어 따라서 이 예제 텍스트는 흔한 지루하다. 하지만 그건 사실이야 질문 보여주기 나는 그것을 위해 노력하고 있습니다. 흔한 안녕 엄마! 바뀌는 라인입니다. 그리고 여기서는 훨씬 더 달라요 복사해야 할 텍스트 게다가. 흔한 독특한 라인이에요. 더있다 복사해야 할 텍스트 게다가. 흔한 뒤에 문자가 와야지 복사되지 않았습니다.
명확성을 위해 추가 출력은 굵게 표시됩니다.
다음으로 시작하는 행 범위를 가져와야 합니다.
독특한 라인이에요
다음 줄로 끝납니다.
흔한
이 범위의 행은 원래 범위의 행 앞에 삽입되어야 합니다. 행 범위와 일치하는 복사본을 약간 수정해야 합니다.
범위를 끝내는 "공통" 줄 자체가 파일 내의 여러 위치에 나타날 수 있습니다.
나는 작동하는 스크립트를 생각해 냈지만 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"을 포함해야 함)을 검색합니다.
- 우리는 이 선행 개행 문자를 제거하고 보존을 업데이트합니다. 이는
H
BTW 명령 때문입니다 . - 이제 편집으로 이동합니다. 고유함 -> 변경됨, 일부 -> 다름,...
- 예약된 공간(변경되지 않은 버전)을 패턴 공간(변경된 버전)에 추가합니다.
- 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
,