다음 내용이 포함된 텍스트 파일 이름이 있습니다 class.txt
.
[serverClass:MAIL]
whitelist.0=LATE
whitelist.1=ONTIME
[serverClass:LETTER]
whitelist.0=FIRST
whitelist.1=SECOND
whitelist.2=THIRD
whitelist.3=FOURTH
[serverClass:NOTES]
whitelist.0=TEST
whitelist.1=CAR
whitelist.2=SPOON
whitelist.3=GAME
블록 중 하나에 새 행을 추가하고 싶다고 가정해 보겠습니다. 예를 들어 블록 SAMPLE
에 새 항목이 있으면 새 항목이 추가되면 숫자가 자동으로 증가해야 합니다. 원하는 출력LETTER
whitelist
[serverClass:MAIL]
whitelist.0=LATE
whitelist.1=ONTIME
[serverClass:LETTER]
whitelist.0=FIRST
whitelist.1=OLD
whitelist.2=NEW
whitelist.3=FOURTH
whitelist.4=SAMPLE
[serverClass:NOTES]
whitelist.0=TEST
whitelist.1=CAR
whitelist.2=SPOON
whitelist.3=GAME
이를 수행할 수 있는 방법이 있습니까 sed
?
답변1
Ralph의 답변에 대한 내 의견에서 말했듯이 이 작업에는 더 나은 도구가 있습니다. 예를 들어 awk
단락 모드를 사용 whitelist.0=SAMPLE
하고 블록이 비어 있으면 추가하고 그렇지 않으면 추출하지 않을 수 있습니다. 마지막 필드(이 경우 행)에서 시작하여 whitelist.NR+1=SAMPLE
블록에 추가합니다.
awk -vRS= -vORS='\n\n' 'BEGIN{z="whitelist.0=SAMPLE";FS="\n"}
/LETTER/{if (/[0-9]=/){split($NF, a, /[.=]/);sub(/0/, a[2]+1, z)}
sub (/$/,"\n"z ,$0)};1' infile
답변2
엄청난! 이제 나는 새로운 것을 배웠습니다. 나는 sed
다양한 (사소한) 대체를 사용했지만 실제로 프로그래밍할 수 있다는 것을 깨닫지 못했습니다. 분명히 이것은 레지스터가 두 개뿐이고 언어가 매우 모호했기 때문에 다소 약한 "기계"였습니다.
입력 변수를 허용하지 않기 때문에 명령줄에서 BLOCK과 ENTRY를 실제 토큰으로 대체하여 준비된 동적 프로시저를 사용하여 호출되는 스크립트 sed
로 설정했습니다 . 교체는 항목 삽입을 구현하기 위한 특정 프로그램을 준비하기 위해 별도의 단순 교체로 수행 됩니다.sh
sed
sed
아래 스크립트가 해당 작업을 수행하는 것 같습니다. 호출되면 addentry
다음과 같이 호출됩니다.
$ addentry LETTER SAMPLE < data
입력 데이터를 재생산하고 삽입된 항목을 출력으로 갖습니다. 필요한 경우 "제자리에서 편집" -i
할 수 있는 옵션이 있다고 가정합니다 sed
.
#!/bin/sh
/bin/sed -n "$(cat << EOF | sed -e "s/BLOCK/$1/g;s/ENTRY/$2/g"
# Initialize hold space with 0
1 { x ; /^$/ s/^$/0/; x }
# Lines outside the interesting block are just printed
/\s*serverClass:BLOCK/,/^$/! { p }
# Lines of the interesting block are considered more in detail
/\s*serverClass:BLOCK/,/^$/ {
# The final empty line is replaced by the new entry, using the line
# counter from the "hold buffer"
/^$/ { g; s/\(.*\)/whitelist.\1=ENTRY/p; s/.*//p; b xx }
# print the line
p
# Jump forward for the block leader (note xx is a label)
/serverClass:/ { b xx }
# Increment hold space counter
# (Only handles 0-9 here; room for improvement)
x; y/0123456789/1234567890/; h
# If the block ends the file without blank line, then add the
# new entry at end.
$ { g; s/\(.*\)/whitelist.\1=ENTRY/p; b xx }
# Label xx is here
:xx
}
EOF
)"
이 흥미로운 도전에 정말 감사드립니다.