Я хотел бы отредактировать файл на месте, добавив строку, только если она еще не существует, чтобы сделать мой сценарий пуленепробиваемым.
Обычно я бы сделал что-то вроде:
cat >> ~/.bashrc <<EOF
export PATH=~/.composer/vendor/bin:\$PATH
EOF
Это также возможно сделать через ansible ( line
+ insertafter=EOF
+ regexp
), но это другая история.
В vi / ex я мог бы сделать что-то вроде:
ex +'$s@$@\rexport PATH=\~/.composer/vendor/bin:$PATH@' -cwq ~/.bashrc
но тогда как я могу проверить, что линия уже существует (и, следовательно, ничего не делать) в идеале, не повторяя ту же строку?
Или, может быть, есть какой-то более простой способ сделать это в редакторе Ex?
substitute
ex-command
kenorb
источник
источник
grep -Fq 'export PATH=~/.composer/vendor/bin:$PATH' ~/.bashrc || ex ...
(илиcat
, в этом отношении)?ex ~/.bashrc -c "if search('export PATH=\~\/.composer\/vendor\/bin:\$PATH')>0 | norm quit | endif | norm Aexport PATH=~/.composer/vendor/bin:$PATH"
export
это команда , поэтому остальная часть строки является словом оболочки, а НЕ присваиванием. Следовательно, в отличие от присваивания переменной (которая не используетexport
), вам нужны двойные кавычки, иначе они будут разбиты на пробел . Также см. Как правильно добавить путь к PATH .Ответы:
Если вы хотите пуленепробиваемый , вы, вероятно, хотите что-то более портативное, чем сложные варианты выше Я хотел бы придерживаться функций POSIX
ex
и сделать это глупо-простым: просто удалите строку, если она есть (независимо от того, сколько раз она там есть), добавьте ее в конец файла, затем сохраните и выйдите:Я закрепил регулярное выражение для дополнительной надежности, хотя я думаю, что почти невозможно случайно сопоставить это регулярное выражение. (Привязка означает использование,
^
и$
поэтому регулярное выражение будет соответствовать, только если оно соответствует всей строке.)Обратите внимание, что
+cmd
синтаксис не требуется для POSIX, а также не является общей возможностью разрешения нескольких-c
аргументов.Есть множество других простых способов сделать это. Например, добавьте строку в конец файла, а затем пропустите последние две строки файла через внешний фильтр UNIX
uniq
:Это очень чисто и просто, а также полностью POSIX-совместимо. Он использует функцию Escape
ex
для внешней фильтрации текста и POSIX-утилиту оболочкиuniq
Суть в том, что
ex
он предназначен для редактирования файлов на месте, и это, безусловно, самый переносимый способ сделать это неинтерактивным способом.vi
Фактически, он предшествует даже оригиналу - названиеvi
для «визуального редактора», а невизуальный редактор, на котором он был построен, былex
.)Для еще большей простоты (и для сокращения его до одной строки) используйте
printf
команду для отправкиex
:источник
Возможное решение - создать функцию для этого:
Сначала мы создаем локальную переменную,
l:res
которая будет использоваться для подсчета количества вхождений строки.Мы используем
global
команду: каждый раз, когда строка соответствует,l:res
увеличивается.Наконец, если
l:res
все еще 0, это означает, что строка не появляется в файле, поэтому мы переходим к последней строке благодаряG
, и мы создаем новую строку,o
в которой мы пишем строку для добавления.Примечание 1 Метод, который я использовал для установки значения,
l:res
немного тяжел и может быть заменен на метод, предложенный @Alex в его ответе, что-то вроде:Примечание 2 Также, чтобы сделать функцию более гибкой, вы можете использовать аргументы:
escape()
в добавлении\
перед символами символа a, который может вызвать проблемы при поиске.Также обратите внимание, что
\
при вызове функции вам все равно придется избегать вызова самостоятельно (мне не удалось избежать\
автоматически):источник
Пытаться:
Обратите внимание, что
:append
не работает внутриif endif
-блок в режиме Ex (см. VimDoc ), поэтому я должен положитьnorm A...
снаружи.источник
Я обычно использую:
источник
Для того, чтобы упростить и избежать присутствия многих
\
, будет добавлена строкаexport PATH=mybin:PATH
.Основная стратегия: заменить
mybin
текст «non- » (весь файл) текстом + mybin-path-definition:или с более дидактическим отступом :
Если у нас есть совпадение:
&
имеет полный текстbashrc
и&
не содержит/mybin:/
так:
ОБНОВЛЕНИЕ : Наконец, мы можем сделать скрипт vim:
chmod 755 и установите его. Применение:
bashrcfix
будьте осторожны: в
\v
режиме=
означает необязательныйисточник
Большинство из этих ответов кажутся сложными, как насчет старых добрых команд оболочки:
Это может быть функция Bash:
РЕДАКТИРОВАТЬ : код выхода grep важен, и в этом случае его необходимо обратить вспять
! grep
;grep -v
не выйдет, как ожидалось в этой ситуации. Спасибо, @joeytwiddle за совет.источник
grep -v
дает вам код выхода, который вы хотите. Но! grep
должен это сделать.-v
просто!
.-F
чтобы неgrep
интерпретировать символы как регулярные выражения, и 2. Использовать-q
вместо перенаправления на/dev/null
. Смотрите мой предыдущий комментарий на вопрос .-q
и-F
варианты? Я думал, что это>/dev/null
было более универсальным среди различных платформ (Sun против HP против Mac OS X против Ubuntu против FreeBSD против ...)