구성 파일에 자동으로 한 줄을 삽입해야 하는데 삽입해야 한다는 경고가 표시됩니다.앞으로여러 줄 바닥글 주석 및 이전의 공백 또는 공백 전용 줄바닥글이 존재하는 경우. 그건,마지막 구성 줄 뒤에 새 줄을 삽입해야 합니다., 원본 파일과 한 줄 비교를 수행합니다. 의사코드에서:
- 파일의 끝으로 이동합니다.
- 파일의 첫 번째(마지막) 구성 줄(즉, 비어 있지 않은 줄, 공백만 있는 줄, 주석만 있는 줄 또는 주석 뒤에 공백이 있는 줄)로 뒤로 이동합니다.
- 현재 줄 뒤에 텍스트를 삽입합니다.
구성 줄에 대한 확장 정규식:^\s*[^[:space:]#]
일반적인 *nix 도구(예: sed
, awk
, ed
또는 ) ex
가 작동해야 합니다.
가능한 해결책과 문제점:
- 사용
tac
두 번 하면 역방향 검색 문제가 아닌 정방향 검색 문제가 됩니다. 이는 단일 명령으로 이 작업을 수행하는 대신 결과를 임시 파일에 저장한 다음 원본 파일을 바꿔야 함을 의미합니다. sed -i
그리고 사용뒤집다장난. 이는 전체 파일을 메모리에 저장하는 것을 의미합니다.ex -c '1' -c '?^\s*[^[:space:]#]?' -c $'a\nmy new line\n.' -c 'wq' /path
, 완전한 파일이 메모리에 저장된다는 것도 배웠습니다.
두 가지 문제를 동시에 해결할 수 있는 솔루션은 없을까요?
시작 파일 예:
# Universe configuration
#
pi = 3 # A good #
e = mc**2 # To within a hair
[cut 200 trillion lines]
#
# END
#
입력 예:
sol { mass = 42, start = 9.2 }
예상 출력:
# Universe configuration
#
pi = 3 # A good #
e = mc**2 # To within a hair
[cut 200 trillion lines]
sol { mass = 42, start = 9.2 }
#
# END
#
답변1
다음과 같은 작업을 수행할 수 있습니다.
file=/some/file
newtext='sol { mass = 42, start = 9.2 }'
tac -- "$file" |
NEWTEXT=$newtext awk -v size="$(wc -c < "$file")" '
$1 ~ /^[^#]/ {
system("dd bs=1 seek=" size - length(footer) " conv=notrunc if=/dev/null")
printf "%s\n%s", ENVIRON["NEWTEXT"], footer
exit
}
{footer=$0 "\n" footer}' 1<> "$file"
그러면 파일이 제자리에 덮어쓰이고 바닥글만 메모리에 저장됩니다. 비표준 GNU tac
명령이 필요합니다. 파일은 일반 텍스트 파일이어야 합니다.
답변2
awk
유일한 해결책(gawk로 테스트):
$ awk '
BEGIN { footer = ""; wl = ""; }
END { while(( getline line < "sol.txt") > 0 ) {
print(line)
}
footer = wl footer
print substr(footer, 0, length(footer)-1);
}
# Blank line
/^[[:blank:]]*$/ {
if (footer) {
footer = wl footer
print substr(footer, 0, length(footer)-1);
footer = ""
}
wl = $0 "\n"
}
# Comment only
/^[[:blank:]]*#/ {
footer = footer $0 "\n";
}
# Configuration line
/^[[:blank:]]*[^[:space:]#]/ {
print(wl footer $0); wl = ""; footer = "";
}
' < universe.txt > universe2.txt
생산:
# Universe configuration
#
pi = 3 # A good #
e = mc**2 # To within a hair
[cut 200 trillion lines]
sol { mass = 42, start = 9.2 }
#
# END
#
한 줄의 차이점:
sh$ diff universe*.txt
8d7
< sol { mass = 42, start = 9.2 }
답변3
이것은 구성 파일이므로 메모리에 맞습니다. 스트림으로 처리할 필요가 없습니다.
newline='
' tab=$(echo | tr '\n' '\t')
old=$(cat foo.config)
footer=${old##*"$newline[!$newline$tab #]"}
if [ "$footer" = "$old" ]; then
footer=
else
footer=${footer#*"$newline"}
fi
head=${old%"$footer"}
echo "$head$text_to_insert$footer" >foo.config.new