используя sed "r" для поиска текста и добавления содержимого файла - PullRequest
0 голосов
/ 28 февраля 2019

Я достаточно хорошо разбираюсь в использовании встроенной функции sed, наряду с ее способностью заменять, а также использовать различные символы в качестве разделителя для его функций, но теперь я обнаружил, что использую функцию "r", чтобы добавитьсодержимое файла добавления после того, как sed обнаружит строку в целевом файле.Я считаю, что это называется командой «ноль или один адрес».

Проще говоря, если файл с именем «letters» содержит

abc
def
ghi

, а «numbers» содержит

123

Тогда использование

sed -i "def r numbers" letters

приводит к тому, что «буквы» становятся

abc
def
123
ghi

Итак, мой вопрос: что произойдет, если «буквы» содержат косые черты?Например, letters2 содержит:

/abc/def/ghi
/def/ghi/jkl
/ghi/jkl/mno

и я хочу добавить «цифры» после строки «/ def / ghi / jkl»?Сначала думают, что простого

sed -i '/def/ghi/jkl r numbers' letters2

будет достаточно, но, конечно, с косой чертой это усложняет ситуацию, учитывая, что это приводит к ошибке «дополнительные символы после команды».Похоже, что в этом случае вы не можете обозначить символ, как вы (например) в стороне замены вещей.Я пробовал (различными способами) такие вещи, как:

sed -i '@/def/ghi/jkl@ r numbers' letters2

, но я продолжаю получать ошибку «unknown command: @».

Я не могу ничего найтионлайн, ни в руководстве о том, как преодолеть это.Любая помощь будет принята с благодарностью!

Ответы [ 2 ]

0 голосов
/ 28 февраля 2019

sed отлично подходит для s / old / new, но для всего остального просто используйте awk:

$ awk 'NR==FNR{new=new $0 ORS; next} {print} $0=="/def/ghi/jkl"{printf "%s", new}' numbers letters
/abc/def/ghi
/def/ghi/jkl
123
/ghi/jkl/mno

Вышеописанное будет работать в любом awk в любой оболочке на любой коробке UNIX для любого содержимого любого из вашихвходные файлы.Он просто создает переменную с именем «new», читая numbers по одной строке за раз и конкатенируя, затем читает letters и печатает текущую строку, а затем печатает содержимое new, если текущая строка является строкой, которую вы 'заинтересован в.

0 голосов
/ 28 февраля 2019

Команде r может предшествовать ноль или один адрес.

Из документации sed:

SedАдреса

Адрес не требуется, но если указано, это должно быть число (которое подсчитывает количество входных строк по всем входным файлам), знак доллара ('$'), который относится к последней строке ввода,или адрес контекста (который состоит из регулярного выражения, перед которым следует разделитель), а затем

В ваших примерах в качестве спецификатора адреса не используется число или $.Единственная оставшаяся опция - это регулярное выражение, заключенное в разделители.Разделителем по умолчанию для regex в sed является косая черта (/).

Поскольку / является разделителем regex, любое использование / внутри regex необходимочтобы быть экранированным (т. е. предшествующим \).
Вам нужна следующая команда:

sed -i '/\/def\/ghi\/jkl/ r numbers' letters2

Чтобы использовать другое разделитель для регулярного выражения (чтобы избежать необходимости экранировать косую черту), выдолжен использовать префикс с обратной косой чертой, когда он используется в качестве открытого разделителя (перед адресом).Не избегайте его, когда он используется после regex.Выход из него внутри regex указывает sed использовать его буквальное значение.

Команда в этом случае:

sed -i '\@/def/ghi/jkl@ r numbers' letters2

Пример, который вы утверждаете, работает (sed -i "def r numbers" letters) не следует этому шаблону и фактически не работает (по крайней мере на macOS sed, который я использую).
Это должно быть sed -i "/def/ r numbers" letters или, если быть более точным, sed -i "/^def$/ r numbers" letters.

...