마지막 구성 줄 뒤에 텍스트를 삽입하려면 어떻게 해야 합니까?

마지막 구성 줄 뒤에 텍스트를 삽입하려면 어떻게 해야 합니까?

구성 파일에 자동으로 한 줄을 삽입해야 하는데 삽입해야 한다는 경고가 표시됩니다.앞으로여러 줄 바닥글 주석 및 이전의 공백 또는 공백 전용 줄바닥글이 존재하는 경우. 그건,마지막 구성 줄 뒤에 새 줄을 삽입해야 합니다., 원본 파일과 한 줄 비교를 수행합니다. 의사코드에서:

  1. 파일의 끝으로 이동합니다.
  2. 파일의 첫 번째(마지막) 구성 줄(즉, 비어 있지 않은 줄, 공백만 있는 줄, 주석만 있는 줄 또는 주석 뒤에 공백이 있는 줄)로 뒤로 이동합니다.
  3. 현재 줄 뒤에 텍스트를 삽입합니다.

구성 줄에 대한 확장 정규식:^\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
#

공통 기능기반으로@StephaneChazelas의 솔루션

답변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

관련 정보