행을 삽입하거나 업데이트하는 가장 깔끔한 방법은 무엇입니까? [복사]

행을 삽입하거나 업데이트하는 가장 깔끔한 방법은 무엇입니까? [복사]

나는 sudoers, sysctl.conf 등에 줄을 추가하기 위해 많은 임시 스크립트를 작성했습니다. 일반적으로 나는 lineinfile ansible 모듈을 사용합니다. 하지만 가끔은 이렇게 할 수 없어서 다음을 사용합니다.

WHAT_I_WANT='my line of text = something'
WHAT_TO_REPLACE='my line of text = .*'
FILE_TO_EDIT=conf_file.conf
if ( ! grep -q "^$WHAT_I_WANT\$" FILE_TO_EDIT ); then
    echo  "$WHAT_I_WANT" >> FILE_TO_EDIT
else
    sed -i "s/$WHAT_TO_REPLACE/$WHAT_I_WANT/g' FILE_TO_EDIT
fi

내 생각에는 이 작업을 수행하는 더 효율적인 방법이 있는 것 같습니다. 이상적으로는 한 줄과 한 언어를 사용하는 것이 좋습니다(또한 정규식 일치, 주석 처리된 줄 제거 및 파일 백업을 허용하는 방식으로). 그러나 그것이 무엇인지는 모르겠습니다.

답변1

  • 제 생각에는 긴 문자열을 대체하기 위해 매우 긴 변수 이름을 사용하는 것은 비생산적입니다.
  • grep/sed 명령에서 변수를 확장하려면 큰따옴표를 사용하십시오.
  • .*변수 할당에 와일드카드 문자를 사용하면파일 이름 확장자 수행(와일드카드)
  • 다음 스크립트는 if 대신 &&성공 또는 실패 시 조건부 실행을 사용합니다 .||

REPL='something'
PATT='my line of text = '
FILE=conf_file.conf

cat $FILE
echo '========='

grep -q "^$PATT" $FILE && (sed -i "s/^$PATT.*$/$PATT$REPL/" $FILE) || (echo "$PATT$REPL" >> $FILE)

cat $FILE

답변2

실제로 간단한 문장은 아니지만 한 번의 호출로 이를 수행할 수 있습니다 sed.

sed -e '
   /pat/{s//repl/g;h;}
   $!b
   G
   s/\n..*//;t
   s/$/repl/
' yourfile

참고: 저는 여러분처럼 쉘 변수를 사용하는 대신 패턴과 대체를 각각 나타내기 위해 의도적으로 pat및 를 사용했습니다. repl기본적으로 sed 코드의 흐름을 방해하는 두 가지 주요 이유가 있습니다. + 정확성을 위해 두 가지를 모두 참조하고 다르게 작동하도록 해야 합니다. 그 일은 당신에게 맡기겠습니다.

흐름: 예를 들어, 파일에 /pat/가 없으면 $!b 명령에 의해 모든 줄이 표준 출력으로 가져오고 G로 추가할 때 마지막 줄은 빈 예약만 확인하므로 t가져오지 않으며 추가가 있습니다. 작업 .

/pat/ 라인이 보이면 s///-ed이며 예약된 영역을 표시합니다. 마지막 줄이 아니면 표준 출력으로 나갑니다. eof의 경우 홀드를 확인하고 null이 아니기 때문에(가정 repl) NONEMPTY패턴 공간에서 홀드가 제거된 후 테스트 경로를 선택합니다.


Perl코드의 축어적 의도와 일치하는 명확성을 제공합니다.

perl -lne '$a += s/pat/repl/g,print}{print q[repl] unless $a'

해석: 이 변수는 $a대체 횟수에 대한 카운터로 사용됩니다. 마지막으로 이전에 대체가 이루어지지 않은 경우 파일에 추가합니다.

변수를 통해 패턴/교체 정보를 제공하는 경우 다음과 같이 할 수 있습니다.

WHAT_I_WANT='my line of text = something'
WHAT_TO_REPLACE='my line of text = .*'
FILE_TO_EDIT=conf_file.conf

perl -li -sn -e '
        $a += s/$pat/$repl/g,print}{print $repl unless $a
' -- -pat="$WHAT_I_WANT" -repl="$WHAT_TO_REPLACE" -- "$FILE_TO_EDIT"

관련 정보