2010-05-01 1 views
1

Мне нужно заменить несколько URL-адресов в текстовом файле некоторым содержимым, зависящим от самого URL-адреса. Скажем, для простоты это первая строка документа по URL-адресу.Как мне нажимать `sed` на вызов оболочки в шаблоне замены?

То, что я пытаюсь это:

sed "s/^URL=\(.*\)/TITLE=$(curl -s \1 | head -n 1)/" file.txt 

Это не работает, так как \1 не установлен. Однако оболочка получает вызов. Могу ли я каким-либо образом переместить переменные соответствия sed в этот подпроцесс?

+0

Возможного дубликат [СЭД - пройти матч внешней команды] (HTTP: // StackOverflow .com/вопросы/11719011/СЭД-PASS-матч-к-внешнего-команды). Хотя этот вопрос старше предлагаемого дубликата, у этого дубликата есть рабочие ответы, тогда как для этого даже принятый ответ не работает. – Ruslan

ответ

2

Таким образом, вы пытаетесь вызвать внешнюю команду из шаблона замены замены sed. Я не думаю, что это можно сделать, $ ... внутри шаблона позволяет вам использовать уже существующую (постоянную) переменную оболочки.

Я бы поехал с Perl, см. Опцию/e в операторе (s /.../.../ e).

ОБНОВЛЕНИЕ: Я был неправ, sed отлично играет с оболочкой, и это позволяет вам сделать это. Но тогда люфт в \1 должен быть экранирован. Попробуйте вместо этого:

sed "s/^URL=\(.*\)/TITLE=$(curl -s \\1 | head -n 1)/" file.txt 
+0

Он работает, попробуйте его с $ (date) внутри шаблона замены. –

+0

Ха, sed более мощный, чем я полагал. Затем попробуйте ускользнуть от люфта с помощью \\ 1 – leonbloy

+0

Действительно, он работает, хотя я клянусь, что попробовал это раньше :) –

1

Попробуйте это:

sed "s/^URL=\(.*\)/\1/" file.txt | while read url; do sed "[email protected]=\($url\)@TITLE=$(curl -s $url | head -n 1)@" file.txt; done 

Если есть повторяющиеся URL-адреса в исходном файле, то будет п^2 из них на выходе. Значение @ в качестве разделителя зависит от URL-адресов, которые не включают этот символ.

+0

Это, в отличие от принятого ответа, похоже он должен работать. Ну, за исключением обратной косой черты внутри двойных кавычек. – zwol

4

Ответ на прием просто неправильный. Доказательство:

Сделать исполняемый скрипт foo.sh:

#! /bin/bash 

echo $* 1>&2 

Теперь запустите его:

$ echo foo | sed -e "s/\\(foo\\)/$(./foo.sh \\1)/" 
\1 
$ 

$(...) расширяется до тогоСЭД запускается.

+0

у вас слишком много обратных косых черт, а группа capturnign пуста .. echo foo | sed "s/\\ (foo \\)/$ (./foo.sh \\ 1)/" – Eddie

+0

Параметр сценария по-прежнему' \ 1' вместо 'foo'. Количество обратных косых черт в этом случае ничего не меняет: оба' echo afoos | sed -e " s/\ (foo \)/x/"и' echo afoos | sed -e "s/\\ (foo \\)/x /" 'output' axs'. Это a Правильно. – Arsen7

+0

'(echo" a a a a a ") | sed "s/a/$ (echo $ RANDOM)/g" '- это, вероятно, проще понять пример, который заменяет каждый экземпляр' a' случайным числом (используя '$ RANDOM'), но все замены то же число, потому что расширение '$ (...)' оболочки происходит до выполнения 'sed', и только первое случайное число было сгенерировано. –

0

Поздний ответ, но убедившись, что люди не получают отброшены ответы здесь - это может быть сделано в гну СЭД с помощью команды e. Далее, например, уменьшает число в начале строки:

echo "444 foo" | sed "s/\([0-9]*\)\(.*\)/expr \1 - 1 | tr -d '\n'; echo \"\2\";/e" 

будет производить:

443 foo 
Смежные вопросы