문자열이 존재하지 않는 경우에만 파일에 텍스트를 추가하는 더 우아한 방법은 무엇입니까?

문자열이 존재하지 않는 경우에만 파일에 텍스트를 추가하는 더 우아한 방법은 무엇입니까?

.desktop 파일에 NoDisplay=true를 추가하고 싶지만 항목이 존재하지 않는 경우에만 가능합니다. 나는 다음과 같이 이 작업을 수행합니다.

grep -q 'NoDisplay=true' '/usr/share/applications/yelp.desktop' || bash -c 'echo "NoDisplay=true" >> /usr/share/applications/yelp.desktop'

동일한 작업을 수행하는 더 짧은 한 줄이 있는지 궁금합니다.

나는 bash 스크립트에서 이 명령을 사용하고 있으며 "bash -c" 명령을 사용해야 합니다.

답변1

GNU가 있다면 sed매우 간단합니다.

sed -zi '/NoDisplay=true/!s/$/\nNoDisplay=true/' file

-z패턴 공간에서 전체 라인을 한 번에 처리하는 옵션 (대용량 파일에는 권장되지 않음) ( ) 설정이 없으면 !끝에 추가되고 개행 문자가 삽입됩니다. 참고: 문자열에서 -i, -z및 를 바꾸는 것은 \n표준이 아니므로 이식성이 없습니다.

답변2

이건 좀 짧습니다.

grep -q 'NoDisplay=true' '/usr/share/applications/yelp.desktop' || echo "NoDisplay=true" >> /usr/share/applications/yelp.desktop

이 Augeas를 위해 특별히 설계된 도구도 있습니다( augtool). 아직 파일 에는 사용하지 않았습니다 .desktop. 따라서 사용 방법을 이해하는 데 도움이 될 수 없습니다.

답변3

사용 sed, 기반이 답변:

sed -i "/^NoDisplay=true\$/h;\${x;/^\$/{s//NoDisplay=true/;H};x}" '/usr/share/applications/yelp.desktop'

s를 탈출하지 않고 분해 $:

# Store the line in the hold space if found
/^NoDisplay=true$/h

# At the end of the file
${
    # Switch to the hold space
    x
    # If it's empty
    /^$/{
        # Replace the line
        s//NoDisplay=true/
        # Store it in the hold space
        H
    }
    # Switch to the hold space
    x
}

할 수는 있지만 그럴 awk일이 없기 때문에제자리에서 편집grepGNU 4.1.0 이전에는 기본적으로 + 와 동일한 작업을 수행했습니다 echo.

답변4

귀하의 접근 방식에서 잠재적으로 우아하지 않은 유일한 것은 bash -cPut this into a Variable (아마도 짧은 이름)을 사용하는 것입니다. 예를 들면 다음과 같습니다.

p='NoDisplay=true' f='/usr/share/applications/yelp.desktop'; grep -q "${p}" "${f}" || echo "${p}" >>"${f}"

다음과 같이 파일 이름을 두 번 지정하여 변수를 사용하는 것을 피하기 위해 리디렉션을 사용하면 더 간결하게 만들 수 있습니다.

p='NoDisplay=true'; (grep -q "${p}" || echo "${p}" >&0) <>/usr/share/applications/yelp.desktop

그러나 그것이 정말 우아한지 여부는 선호의 문제일 수 있습니다.

어쨌든 변수를 전달하더라도 패턴은 여전히 ​​두 번 지정되어야 합니다. 나는 이것을 피할 방법을 상상할 수 없습니다.

사용되는 또 다른 변형은 sed다음과 같습니다.

p='NoDisplay=true'; sed -n "/${p}/q;\$a${p}" <>/usr/share/applications/yelp.desktop >&0

명령 뒤에 추가할 텍스트(이 경우 패턴 변수)가 오기 때문에 GNU가 필요합니다 sed(일반적으로 Linux에서 발견됨) .a

POSIX의 경우에도 마찬가지입니다 sed.

p='NoDisplay=true'; sed -n "/${p}/q;\$a\\
${p}
" <>/usr/share/applications/yelp.desktop >&0

관련 정보