Проверьте, содержит ли файл многострочную строку в bash - PullRequest
0 голосов
/ 23 декабря 2018

Фон

Я пишу функцию для добавления файла в мой каталог $HOME с именем .bash.local.

➡️ .bash.local поступает через .bash_profile.

Однако я хочу условно добавить к .bash.local тогда и только тогда, когда файл делаетне уже содержит содержимое $BASH_CONFIGS.

Что нужно помнить

Моя операционная система выбора MacOS Mojave, поэтому некоторые версии приложений командной строки будут отличаться(например, grep на Mac - BSD grep, а не GNU grep).

⚠️ append_to_bash_local ()

append_to_bash_local() {
    local LOCAL_BASH_CONFIG_FILE="$HOME"/.bash.local

    declare -r BASH_CONFIGS="
# TOOL_NAME - TOOL_DESCRIPTION.
# Add tool configurations here
"

    # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    # If needed, add the necessary configs in the
    # local shell configuration file.

    if ! grep "^$BASH_CONFIGS" < "$LOCAL_BASH_CONFIG_FILE" &> /dev/null; then
        # this block never runs, even if the contents of $BASH_CONFIG
        # are NOT present in $HOME/.bash.local
    fi

}

Ответы [ 2 ]

0 голосов
/ 23 декабря 2018

С небольшой помощью @ kamil-cuk я смог создать более улучшенную версию append_to_bash_local().

⚠️ Обратите внимание, потому что я на MacOS Mojave& по умолчанию установлены оба BSD-grep & BSD-sed и не установлены ни GNU-grep, ни GNU-sed, я был вынужден найти другое решение для усечения символов новой строки с символом ASCII NUL .К счастью, у @ kamil-cuk было решение hacky с использованием tr.

Ниже приведена улучшенная версия append_to_bash_local().

⚠️ append_to_bash_local()

  1. Сначала проверьте, не существует ли файл с [ ! -e "$LOCAL_BASH_CONFIG_FILE" ].
  2. Во-вторых, используйте -q с grep, чтобы заставить его замолчать.
    • ➡️ Обязательно поставьте ! (не) перед grep -q, чтобы убедиться, что состояние выхода инвертировано, поскольку мы проверяем, не содержит ли файл содержимое $BASH_CONFIGS.
  3. Наконец, используйте "$(<<<"$BASH_CONFIGS" tr '\n' '\01')" < <(less "$LOCAL_BASH_CONFIG_FILE" | tr '\n' '\01'), чтобы усекать символы новой строки с символом ASCII NUL в обоих$BASH_CONFIGS & $LOCAL_BASH_CONFIG_FILE.

    append_to_bash_local() {
    
        local LOCAL_BASH_CONFIG_FILE="$HOME"/.bash.local
    
        declare -r BASH_CONFIGS="
        # TOOL_NAME - TOOL_DESCRIPTION.
        # Add tool configurations here
        "
    
        # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    
        # If needed, add the necessary configs in the
        # local shell configuration file.
    
        if [ ! -e "$LOCAL_BASH_CONFIG_FILE" ] || ! grep -q "$(<<<"$BASH_CONFIGS" tr '\n' '\01')" < <(less "$LOCAL_BASH_CONFIG_FILE" | tr '\n' '\01'); then
            printf '%s\n' "$BASH_CONFIGS" >> "$LOCAL_BASH_CONFIG_FILE"
        fi
    
    }
    
0 голосов
/ 23 декабря 2018

Вы рядом.В любом случае, небольшие исправления:

  • используйте разделенные нулями grep -Z для сопоставления шаблонов с символами новой строки.Если вы думаете об этом, это немного хакерски, но работает каждый раз.
  • используйте -q для grep, чтобы заставить его замолчать.
  • и не вводите файл в stdingrep, просто скажите grep имя файла.
  • проверьте, существует ли файл

append_to_bash_local() {
     local LOCAL_BASH_CONFIG_FILE="$HOME"/.bash.local
     declare -r BASH_CONFIGS="
# TOOL_NAME - TOOL_DESCRIPTION.
# Add tool configurations here
"
    if
           # if a file does not exists
           [ ! -e "$LOCAL_BASH_CONFIG_FILE" ] ||
           # if it doesn't have the content of BASH_CONFIGS
           ! grep -q -z "$BASH_CONFIGS" "$LOCAL_BASH_CONFIG_FILE"; then
        echo appending
        echo "$BASH_CONFIGS" >> "$LOCAL_BASH_CONFIG_FILE"
    else
        echo not appending
    fi

}
...