Как использовать sed для замены определенной строки строковой переменной?

Вы можете запустить сценарий при загрузке, передав параметр загрузки ядра scriptв файлах конфигурации загрузчика ISO.

Предполагается, что вы используете пакет archisoдля создания образа ISO.

Поместите свой сценарий где-нибудь, например releng/airootfs/root/install.sh, и установите для сценария бит разрешения на выполнение.

В releng/efiboot/loader/entries/archiso-x86_64-cd.confдобавьте script=/root/install.shк строке options.

В releng/syslinux/archiso_sys.cfgдобавьте script=/root/install.shк строке APPEND.

1
02.11.2020, 19:57
7 ответов

Предполагая, что значение $substituteне содержит специальных символов, вы можете просто выполнить:

line=1
substitute=hello1
sed -i "${line}s/.*/$substitute/"  file.txt
1
18.03.2021, 22:53

Сperl:

export line substitute
perl -pi -e '$_ = $ENV{substitute}. "\n" if $. == $ENV{line}' file.txt

то же самое с GNUawk:

export line substitute
gawk -i inplace 'NR == ENVIRON["line"] {$0 = ENVIRON["substitute"]}
                 {print}' file.txt

Использование sedздесь не идеально, даже с теми, которые поддерживают параметр perl -, подобный -i, так как нам потребуется выполнить некоторую пост--обработку значения $substitute, если оно может содержать обратную косую черту, &, разделитель команд sили символы новой строки. См. Как гарантировать, что строка, интерполированная в подстановку `sed `, пропускает все метасимволы для получения подробной информации об этом.

7
18.03.2021, 22:53

Без дополнительной информации должна работать следующая awkпрограмма:

awk -v where="$line" -v what="$substitute" 'FNR==where {print what; next} 1' file.txt
  • Переменные оболочки $lineи $substituteбудут импортированы в переменные awkwhereи what.
  • При обработке файла он по умолчанию будет просто печатать текущую строку (кажущуюся рассеянной 1за пределами блока правил{... }).
  • Когда счетчик -строк файла FNRравен номеру строки, хранящемуся в where, вместо этого мы печатаем заменяющую строку whatи пропускаем выполнение до следующей входной строки.

Обратите внимание, что awkне редактирует файлы в месте -, поэтому вам придется перенаправить вывод и переименовать результирующий файл, как только вы будете удовлетворены. В качестве альтернативы, с достаточно новыми версиями GNU awk, вы можете использовать опцию -i inplaceдля изменения файла в месте -.

Обратите внимание , что (, как указано αғsнιη/Стефаном Шазеласом/Эдом Мортоном ), приведенное выше поведение покажет ошибочное поведение, если ваша substituteстрока содержит литерал \, так как этот метод расширяет escape-последовательности. В этом случае альтернативное решение на основеawk-в ответе Стефана Шазела с экспортом переменной и ссылкой на нее как ENVIRON["substitute"]поможет (см. этот ответ для получения дополнительной информации ).

2
18.03.2021, 22:53

Предполагая line >0и всегда int , вы могли бы сделать:

<infile head -n$(($line-1)); printf '%s\n' "$substitute"; tail -n +$(($line+1)) infile

Обратите внимание, что это добавит значение $substituteв конец файла, если строка _номер $line> _номер файла _из _строк

2
18.03.2021, 22:53
$   line=1 substitute=hello1
$ sed -nf - <<eof file 
  $line r $(t=$(mktemp);printf '%s\n' "$substitute" > "$t";echo "$t")
  $line!p
eof

Мы используем heredoc для передачи кода sed. Код sed читает файл и помещает содержимое jts в стандартный вывод и подавляет исходную строку благодаря опции -n.

1
18.03.2021, 22:53

Если:

  • $lineсодержит фактический номер строки файла (не равно -нулю, не больше последней строки )и
  • $substituteне равно одному периоду(.)

тогда вы можете использовать скрипт ed:

printf '%dc\n%s\n.\nw\nq' "$line" "$substitute" | ed -s input

Это отправляет несколько строк команд в качестве входных данных дляed:

  1. cизменить строку, представленную$line
  2. на значение $substitute
  3. завершите изменение с помощью.
  4. wзаписать измененный файл обратно на диск
  5. qв комплекте

Конечно, поскольку проверки -на ошибки нет, $lineи $substituteнеобходимо соблюдать предположения, приведенные выше. Окружающий сценарий оболочки мог бы проверить работоспособность -переменной $line, но ввод голого .в качестве входных данных для edпотребовал бы дополнительных усилий.

0
18.03.2021, 22:53
sed ""$line"s/.*/"$substitute"/g" filename
0
18.03.2021, 22:53

Теги

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