bash 스크립트로 줄 교체 줄 캐치를 읽는 방법은 무엇입니까?

bash 스크립트로 줄 교체 줄 캐치를 읽는 방법은 무엇입니까?

구성 파일 세트가 있고 해당 구성 줄이 포함된 테마 디렉터리의 모든 파일에서 일부 구성을 주석 처리하고 싶습니다.

구성 파일은 다음과 같습니다.

...
someconfig = comand()#@#$#$@#
             asdbaksdjbkajsbd
             asdasdjhavshdjvas
...

그래서 나는 bash 스크립트를 사용하여 이 작업을 수행하기로 결정했습니다.

#!/bin/bash
filename='myconfigfile.conf'
echo Start ...
while IFS= read -r line; do
    if [[ $line =~ ^someconfig.* ]]; then
        echo "$line"
        sed -i 's/$line/\#\$line/g' $filename 
    fi
done < $filename

이 파일에서 선호되는 출력 라인:

...
#someconfig = comand()#@#$#$@#
#             asdbaksdjbkajsbd
#             asdasdjhavshdjvas
...

나는 이것을 Python으로 했지만 너무 복잡하게 만들지 않고 bash 스크립트에서 할 수 있는지 확인하고 싶었습니다.

부울을 사용하고 모든 파일을 반복하여 다음 줄이 공백이 아닌 문자로 시작하는지 감지하여 모든 파일에서 이러한 줄을 변경하는 솔루션이 있지만 부품을 바꾸는 방법을 모르고 내 코드가 ' 작동하지 않는 것 같습니다.

어떤 도움이라도 대단히 감사하겠습니다.

답변1

이 문제의 구현은 문제가 많고 비효율적입니다.

파일을 한 줄씩 읽고 sed입력 줄에서 명령을 구성합니다. 줄에 정규식 특수 문자(예: .^$[]등)가 포함되어 있으면 이 명령이 예기치 않게 작동할 수 있습니다.

sed그런 다음 변경해야 하는 각 줄에 대해 전체 파일을 한 번씩 처리해야 합니다. 전체 입력 파일을 반복적으로 처리하는 대신 각 라인을 개별적으로 처리할 수 있습니다.

awk파일을 처리하고 임시 출력 파일을 처리하는 쉘 스크립트 래퍼를 사용하는 것이 좋습니다 . ( 또는 awk등의 내부 편집 .)sedperl

#!/bin/bash
filename='myconfigfile.conf'

temp=${filename}.temp

awk '/^[^   ]/ { comment=0 }     # stop commenting if line starts with non-space.
     /^someconfig/ { comment=1 } # start commenting if line starts with "someconfig"
     comment {$0 = "#" $0}       # prepend "#" to whole line ($0)
     { print }' $filename > $temp && mv -f $temp $filename || rm -f $temp

선택적으로 규칙을 추가할 수 있습니다.

     /^[    ]*$/ { comment=0 }   # stop commenting on empty line or space only

빈 줄이나 공백만 포함된 줄이 나타나면 주석 달기를 중지하세요.

에는 공백과 탭이 포함되어 있습니다 [^ ].[ ]

스크립트 번호발각어떤 들여쓰기. 0이 아닌 한 줄 "#"의 모든 항목(들여쓰기 포함) 앞에 추가됩니다.comment

답변2

쉘에서 이미 파일을 한 줄씩 처리하고 있는데 왜 sed나 awk를 사용합니까? 이와 같은 작업을 수행하기 위해 다른 많은 프로그램을 사용할 필요는 없습니다.

[[ $line =~ '^[[:space:]]' ]] || indent=0
if [[ $line =~ ^someconfig.* || $indent ]]
then
    echo -n "#"
    indent=1
fi
echo "$line"

루프 출력을 임시 파일로 보낸 다음 mv(아주 좋은) awk 답변에 표시된 대로:

done <$file >$file.tmp && mv $file.tmp $file

나는 일반적으로 명령이 실패하더라도 이런 일이 발생하지 않도록 이름 바꾸기를 &&로 연결하는 것을 선호합니다. 또한 오타가 있어서 죄송합니다. 저는 이 글을 휴대폰으로 입력하고 있어서 휴대폰 키보드로 코딩하는 데 어려움을 겪었습니다. :)

관련 정보