여러 번 반복되는 일련의 줄이 포함된 텍스트 파일이 있습니다. 예를 들어:
param id: 0
value: 2
description: "hello"
param id: 1
value: 3
description: "world"
이사하고 싶어요설명하다이상값그리고 변화매개변수 ID더 높은 값으로, 예를 들어매개변수 ID0 대신 1. 이 작업을 수행하기 위해 스크립트를 사용하고 싶습니다. 누구든지 이 작업을 수행할 수 있는 명령으로 나를 도와줄 수 있습니까?
답변1
@MelBursian이 이미 댓글에서 제안했듯이 저도 awk
동의합니다 sed
.
awk '
BEGIN { OFS=FS=": " }
{
if ($1 == "param id") {
$2 += 1;
}
if ($1 == "value") {
val=$0; getline;
print; print val;
next;
}
print;
}
' file
답변2
그러면 "value:"로 시작하는 모든 줄이 해당하는 다음 줄로 전환됩니다.
sed '/^value: /{N;s/^\(.*\)\n\(.*\)$/\2\n\1/}'
설명하다:
/^value: / { ... }
...
중괄호로 묶인 명령은 정규식 "^value:"(여기서는 가짜)와 일치하는 줄에 대해서만 실행됩니다.N
패턴 공간에 다음 줄을 추가합니다. 따라서 여기에서 개행 문자로 연결된 두 줄을 작업할 수 있습니다.s/^\(.*\)\n\(.*\)$/\2\n\1/
개행 문자 앞의 텍스트와 개행 문자 뒤의 텍스트를 전환합니다.s/something/else/
"something"을 "else"로 바꾸는 대체 명령입니다.^\(.*\)\n\(.*\)$
패턴 공간의 시작부터 개행 문자까지의 모든 텍스트를 일치시키고 이를 표현식 1로 저장합니다. 그런 다음 패턴 공간 끝까지의 다른 모든 문자는 표현식 2로 저장됩니다.\2\n\1
표현식 2 뒤에 줄 바꿈 문자가 오고 그 다음에는 표현식 1이 대체용으로 사용됩니다.
답변3
sed
가치를 추가하는 데 사용하는 것은 적극 권장되지 않습니다. 이러한 유형의 작업에는 적합한 도구가 아닙니다. 하지만 꼭 해야 한다면 sed
이는 GNU에서만 작동합니다 sed
.
sed -rn '/^param/{s/(.*)([0-9]+)/echo \1$((\2+1))/e;p;n;h;n;p;x;p;n;p}' file
-r
확장 정규식을 활성화합니다.-n
sed
자동 인쇄를 비활성화했습니다 ./^param/
패턴으로 시작하는 줄을 검색합니다param
.s/(.*)([0-9]+)/echo \1$((\2+1))/e
이제 해당 줄에서 검색/바꾸세요. 번호를 검색하여([0-9]+)
교체한echo \1$((\2+1))
후 실행합니다.e
in은s///e
셸에서 일치하는 패턴을 실행하는 수정자입니다.p;
그런 다음 변경된 줄을 인쇄하십시오.n;
패턴 공간에 다음 라인(행)을 로드합니다value
.h;
행을 예약된 공간에 복사합니다.n;p;
다음 줄(이description
줄)을 로드하고 인쇄하세요.x;
모드를 바꾸고 공간을 유지하세요.p;
이 줄을 인쇄하세요.n;p
다음 줄(빈 줄)을 로드하고 인쇄합니다.
샘플 입력으로 출력:
param id: 1
description: "hello"
value: 2
param id: 2
description: "world"
value: 3
답변4
선 이동은 POSIX를 사용하여 수행하는 것이 가장 쉽습니다 ex
. 숫자 증분을 수행하는 것이 가장 쉽습니다 awk
. 다행히 ex
외부 도구를 통해 특정 행을 필터링할 수 있습니다.
printf %s\\n 'g/description/m-2' 'g/param id/.!awk "++\$NF"' x | ex file
영어로 번역하면 첫 번째 명령은 "'설명'이라는 단어가 포함된 모든 줄을 한 줄로 이동"입니다.
(거기에 2가 있는 이유는 문자 그대로 번역하면 "이 줄을 두 줄 뒤에 있는 지점으로 이동"하기 때문입니다.)
두 번째는 'param id'가 포함된 모든 행을 필터링하는 것입니다 awk
.
명령은 awk
"줄의 마지막 필드를 증가시키고 결과가 정확히 0이 아닌 한 줄을 인쇄합니다. :)"입니다.
x
"저장 후 종료" 입니다.