Если не имеет значения, где в списке параметров находится новый, вы можете
sed '/_configure_flags *:=/ a\
--add-module=$(MODULESDIR)/ngx_pagespeed \\
' file
light_configure_flags := \
--add-module=$(MODULESDIR)/ngx_pagespeed \
$(common_configure_flags) \
--with-http_gzip_static_module \
...
Чтобы добавить после строки «common_configure_flags», вы можете:
sed -r '
# when the line ends with a backslash
# add the new line with a backslash
/\$\(common_configure_flags\)[[:blank:]]*\\$/ a\
--add-module=$(MODULESDIR)/ngx_pagespeed \\
# when the line does not end with a backslash,
# add a backslash, then
# add the new line without a backslash
/\$\(common_configure_flags\)[[:blank:]]*$/ {
s/$/ \\/
a\
--add-module=$(MODULESDIR)/ngx_pagespeed
}
' file
Вы можете использовать awk
для добавления логики добавления строки и column
для переформатирования конечного выходного файла. Предполагая, что у вас есть права на запись в папки /etc/
и /tmp/
tempfile=$(mktemp /tmp/tmpfile.XXXXXXXX)
Это создаст временный файл в пути /tmp/
, в который вы можете записать вывод awk
и повторно -направить его обратно в исходный файл
awk '$3 ~ "ext[2-4]"{ $4=$4",nodev" }1 ' /etc/fstab | column -t > "$tempfile" && mv -- "$tempfile" /etc/fstab
Часть column -t
просто избыточна и нужна для того, чтобы выходной файл выглядел более читабельным, а не для того, чтобы сделать его беспорядочным и громоздким.
Конечно, через десять минут после публикации вопроса я, наконец, смог заставить его делать то, что я хочу, со следующим:
sed -r '/^[^#].*[ \t]+\/[^[:space:]].*ext[2-4]/s/defaults/defaults,nodev/g' /etc/fstab
Если у кого-то есть более понятный или надежный ответ, я бы хотел его услышать. Спасибо!
Исключение совпадений сложно поддерживать. Безопаснее сопоставлять только тот раздел, который вы хотите. А для соответствия только одной строке завершающая буква «g» не нужна.
sed -r 's#(/home\s.*defaults)\s#\1,nodev #' /etc/fstab
Вот более простой sed
подход:
$ sed -E 's|(\s/\S+\s+ext[2-4]\s+defaults)|\1,nodev|' fstab
# /etc/fstab
# Created by anaconda on Wed Feb 21 09:37:23 2018
/dev/mapper/vg1-lv_root / ext4 defaults 1 1
/dev/mapper/vg1-lv_home /home ext4 defaults,nodev 1 2
tmpfs /dev/shm tmpfs defaults 0 0
Хитрость заключается в том, чтобы найти пробел, за которым следует /
и один или несколько не -пробельных символов (\s/\S+
), затем ext[2-4]
, но только если ему предшествует пробел (\s+ext[2-4]
), больше пробелов и defaults
. Это должно соответствовать только тем случаям, которые вас интересуют. Поэтому, если это действительно так, замените все совпадение самим собой плюсnodev
:\1,nodev
.
Однако я не уверен, насколько это портативно. -E
для расширенных регулярных выражений поддерживается многими реализациями sed
, но это не POSIX. Для более переносимого подхода вы можете попробовать ту же идею в Perl :
$ perl -pe 's|(\s/\S+\s+ext[2-4]\s+defaults)|\1,nodev|' fstab
# /etc/fstab
# Created by anaconda on Wed Feb 21 09:37:23 2018
/dev/mapper/vg1-lv_root / ext4 defaults 1 1
/dev/mapper/vg1-lv_home /home ext4 defaults,nodev 1 2
tmpfs /dev/shm tmpfs defaults 0 0
В обоих случаях для редактирования файла на месте используйте-i
:
perl -i -pe 's|(\s/\S+\s+ext[2-4]\s+defaults)|\1,nodev|' fstab
sed -E 's|(\s/\S+\s+ext[2-4]\s+defaults)|\1,nodev|' fstab
Или, для BSD или OSXsed
:
sed -i '' -E 's|(\s/\S+\s+ext[2-4]\s+defaults)|\1,nodev|' fstab
Обратите внимание, что вышеприведенное предполагает, что опция defaults
будет либо единственной, либо, по крайней мере, последней. Они потерпят неудачу, если у вас есть что-то вроде nodev,defaults
, например.