Редактировать файл на основе наличия строки

Вам следует добавить строку в /etc/fstab, которая описывает, как монтировать тома. Читая страницу с man fstab, вы должны обратить внимание на опцию user. Это решение не использует sudo, но я предполагаю, что ваша конечная цель - разрешить обычным пользователям монтировать диск.

4
02.11.2018, 08:48
3 ответа

Можно попробовать так: если строка совпадает, просто скопируйте ее на hстарый пробел, а затем sподставьте значение.
В строке la$t exпоменяйте местами пробел удержания и пробел шаблона, затем проверьте, пуст ли последний. Если он не пуст, это означает, что замена уже была сделана, поэтому ничего не нужно делать. Если он пуст, значит, совпадение не найдено, поэтому замените пространство шаблона на SMEAR=-5 и добавьте к текущей строке в буфере удержания. Наконец, exснова измените:

sed '/SMEAR/{h;s/.*/SMEAR=-5/};${x;/^$/{s//SMEAR=-5/;H};x}' infile

Вышеприведенное является синтаксисом gnu sed. Portable:

sed '/SMEAR/{
h
s/.*/SMEAR=-5/
}
${
x
/^$/{
s//SMEAR=-5/
H
}
x
}' infile

Альтернативный способ с ed:

ed -s infile<<\IN || printf %s\\n SMEAR=-5 >> infile
/SMEAR.*/s//SMEAR=-5/ 
w
q
IN

Если ни одна строка не соответствует образцу, ed выдаст ошибку, поэтому будет выполнена вторая команда (printf...) для добавления строки в файл. В противном случае ed отредактирует файл на месте.


Если у вас есть значение SMEAR, сохраненное в переменной, например,

var=-7

вы выполните:

sed '/SMEAR/{h;s/.*/SMEAR='"$var"'/};${x;/^$/{s//SMEAR='"$var"'/;H};x}' infile

или

ed -s infile<<IN || printf %s\\n "SMEAR=${var}" >> infile
/SMEAR.*/s//SMEAR=${var}/ 
w
q
IN
5
27.01.2020, 20:47

Похоже, что последовательность строк не имеет значения для вашего случая. Учитывая это, я бы использовал ex и просто:

  1. Удалите все экземпляры SMEAR;
  2. Вставьте нужную вам строку.

Это можно сделать так:

printf '%s\n' 'g/SMEAR/d' '$a' 'SMEAR=-5' . x | ex file.txt

Первая команда - globally delete all lines that match the regex /SMEAR/.

Следующая команда - append после последней строки ($) строка SMEAR=-5. Через заканчивается текст для добавления.

Команда x сохраняет изменения и завершает работу.

Каждая команда завершается новой строкой с помощью printf '%s\n', чтобы отправить их в ex.


Также смотрите очень похожее решение, о котором я писал некоторое время назад в обмене стеками vi/Vim.


Чтобы проверить изменения, распечатав измененный файл в командной строке без сохранения изменений, замените x двумя командами %p 'q!' следующим образом:

printf '%s\n' 'g/SMEAR/d' '$a' 'SMEAR=-5' . %p 'q!' | ex file.txt

% означает "весь буфер", что и будет pраспечатано.

q! означает "выйти, отбросив изменения".

Чтобы сохранить изменения в новый файл, замените %p на w newfile.txt следующим образом:

printf '%s\n' 'g/SMEAR/d' '$a' 'SMEAR=-5' . 'w newfile.txt' 'q!' | ex file.txt

Это wзаписывает измененный буфер в newfile.txt.

В качестве альтернативы вы можете сделать это в самом начале, чтобы создать резервную копию, а затем сохранить измененное содержимое файла в исходное место, file.txt, например, так:

printf '%s\n' 'w file.txt.bak' 'g/SMEAR/d' '$a' 'SMEAR=-5' . x | ex file.txt

Edit: На самом деле вам не нужно использовать q! ; достаточно опустить x, чтобы избежать сохранения изменений. Когда ex получает EOF при попытке прочитать дальнейший ввод, он завершается и не сохраняет изменения.

6
27.01.2020, 20:47

Или реализуя идею подстановочного знака (удалить любую/все существующие строки (с ), которые содержат SMEAR, а затем вставьте нужную строку )с инструментами каменного -века:

(grep -v '^SMEAR=' file1; echo 'SMEAR=-5') > file1.tmp  &&  cp file1.tmp file1  &&  rm file1.tmp

или, если вас это не волнует о сохранении атрибутов (, например, разрешений )и жесткие ссылки на file1,ты мог бы сделать

(grep -v '^SMEAR=' file1; echo 'SMEAR=-5') > file1.tmp  &&  mv file1.tmp file1

или, если у вас есть sponge, вы можете сделать

(grep -v '^SMEAR=' file1; echo 'SMEAR=-5') | sponge file1
1
27.01.2020, 20:47

Теги

Похожие вопросы