Bash 스크립트 터미널에서 텍스트 찾기 및 바꾸기

Bash 스크립트 터미널에서 텍스트 찾기 및 바꾸기

/home/count/1/details/info.txt다음과 같은 파일이 있습니다

title1 {
key1 value1
key2 value2
key3 value3
}

info {
name1 text
post1 anything
salary 1
work day1
work day2
work day3
}

work {
department sell
store ground
remarks
}

contact {
required No
}

이제 나에겐 필요해변화위에서:

title1 {
key1 value1
key2 value2
key3 value3
}

info {
name1 text
post1 anything
salary 1
work day1
work day2
work day3
work day4
work day5
work day8
}

work {
department sell
store ground
remarks
Absent No
}

contact {
required No
}

work day4, work day5, 정보 그룹에 3개의 새로운 값이 추가되었습니다 work day8. 작업 그룹은 새로운 값, 즉 을 얻습니다 Absent.

제목(예: title1, 정보, 작품)은 고정되어 변경할 수 없습니다. 그러나 {} 사이의 값은 동적으로 가변적이며 임의의 값이 될 수 있습니다. 하지만 핵심 작업은 고정되어 있어 추가 또는 삭제만 가능하고 수정은 불가능합니다.

이 작업을 수행하려면 bash 파일을 작성해야 했습니다. 최소 버전의 ubuntu 20.04 서버에서만 터미널을 사용할 수 있습니다.

아이디어, 제안, 도움이 있으신가요?

감사해요

답변1

그리고 perl:

perl -0777 -pi -e '
  s{^info\s*\{.*?\K(?=\})}{join "", map {"work day$_\n"} 4,5,8}mse;
  s{^work\s*\{.*?\K(?=\})}{Absent No\n}ms' /home/count/1/details/info.txt

답변2

awk 'BEGIN {RS=ORS="\n\n"};
     /^info {/ { gsub("}","work day4\nwork day5\nwork day8\n}") };
     /^work {/ { gsub("}","Absent No\n}") };
     1' info.txt 

이는 awk에게 입력 파일을 한 번에 한 단락씩 읽도록 지시합니다(즉, 입력 레코드 구분 기호를 RS하나가 아닌 두 개의 줄 바꿈으로 구분된 레코드로 설정함으로써 \n\n). 또한 출력 레코드 구분 기호를 와 동일하게 설정하여 RS출력 레코드 사이에 빈 줄이 있도록 합니다.

그런 다음 이 함수를 사용하여 일치하는 각 단락("info {" 또는 "work {"로 시작하는 단락)의 끝 gsub()전에 추가 줄을 추가합니다 . }실제로는바꾸다이 레코드 끝에는 }추가 줄이 있습니다.그리고a }- 이는 추가 행을 삽입하는 것과 사실상 동일합니다.

마지막은 1awk의 약어 print이며 수정 여부에 관계없이 모든 레코드를 인쇄합니다.

답변3

또한 awk단락 모드에서 다음 코드를 시도해 볼 수 있습니다.


awk -v s1="Absent No\n" -v s2="work day4\nwork day5\nwork day8\n"  -v OFS="\n" -v RS= -v ORS='\n\n' '$1 == "work" {sub(/}/, s1"&")} $1 == "info" {sub(/}/, s2"&")} 1' file
title1 {
key1 value1
key2 value2
key3 value3
}

info {
name1 text
post1 anything
salary 1
work day1
work day2
work day3
work day4
work day5
work day8
}

work {
department sell
store ground
remarks
Absent No
}

contact {
required No
}

답변4

sed -i -e '
  /^info {/,/}/ s/}/work day4\nwork day5\nwork day8\n&/

  /^work {/,/}/ s/}/Absent No\n&/
' /home/count/1/details/info.txt

perl -i -lpe '
  /^info \{/.../}/ and /}/ && do{
  print for map { "work day$_" } 4,5,8}; 

  /^work \{/.../}/ and /}/ &&
    print "Absent No";
' /home/count/1/details/info.txt

관련 정보