Use um separador diferente que não contenha nenhum dos caracteres da variável.
Por exemplo,
sed "s|^|$URL|"
(Se você usa / como o separador e o padrão ou a substituição também contém / , então você precisa escapar deles.)
Eu tenho o URL (veja abaixo) de uma determinada página da web que lista muitos diferentes versões de um pacote de software.
URL=http://ftp.gnu.org/gnu/wget/
O seguinte one-liner me traz a última versão do tar ball e sua assinatura arquivo fora do HTML.
wget -qO- http://ftp.gnu.org/gnu/wget/ | grep tar | cut -d\" -f6 | tail -n4 | grep gz
Provavelmente não o forro mais curto e eficiente, mas ei, estou aprendendo e Estou aberto para feedback. O resultado do acima é isto:
wget-1.15.tar.gz
wget-1.15.tar.gz.sig
Agora, o próximo passo lógico (pelo menos para mim) é canalizar a saída acima para
sed e acrescente o $URL à frente de cada linha para que a saída pareça
como:
http://ftp.gnu.org/gnu/wget/wget-1.15.tar.gz
http://ftp.gnu.org/gnu/wget/wget-1.15.tar.gz.sig
E então eu quero redirecionar isso de volta para wget para baixar os arquivos.
A pergunta é a seguinte: Como eu adiciono o valor da variável bash $URL ao
a frente de cada linha de saída usando sed ? Eu tentei o seguinte:
sed "s/^/$URL/"
Mas isso só me dá o erro:
sed: -e expression #1, char 11: unknown option to 's'
Eu também sei que o conceito básico é bom, porque quando eu uso o seguinte, eu obter bons resultados ...
VAR="Gorauskas, "
echo "Jonas" | sed "s/^/$VAR/"
Então, meu palpite é que eu preciso de alguma forma escapar todo o caractere / no
$URL variable ... Estou no caminho certo?
O que você faz até agora pode ser substituído por uma chamada awk :
wget ... | awk -F\" '$6 ~ "gz$" { lastline=thisline; thisline=$6;}; '\
'END {print lastline; print thisline;}'
E, claro, o awk também pode adicionar o URL:
awk -F\" -v baseurl="http://ftp.gnu.org/gnu/wget/" \
'$6 ~ "gz" { lastline=thisline; thisline=$6;}; '\
'END {print baseurl lastline; print baseurl thisline;}'
Você pode usar a opção wget de --base aqui:
wget -qO- http://ftp.gnu.org/gnu/wget/ |
cut -d\" -sf6 |
grep '\.tar\.gz' |
tail -n2 |
wget -i - --base=http://ftp.gnu.org/gnu/wget/
Você também pode fazer tudo diretamente assim:
wget -qO- http://ftp.gnu.org/gnu/wget/ | grep tar.gz | cut -d\" -f6 |
tail -n2 | xargs -I{} wget http://ftp.gnu.org/gnu/wget/{}
Isso passa a saída do primeiro wget para xargs que substitui a string {} com cada um dos resultados do comando canalizado.
E você pode pular algumas etapas de análise com alguns truques:
wget -qO- http://ftp.gnu.org/gnu/wget/ | tac | grep -Pom 2 'href="\K(.+?.tar.gz)' |
xargs -I{} wget http://ftp.gnu.org/gnu/wget/{}
Aqui, estamos usando PCREs ( -P ) com grep e -o para que apenas imprima a parte correspondente da linha e -m 2 para imprimir apenas as duas primeiras correspondências. A chamada tac inverte a entrada para que as primeiras 2 correspondências sejam realmente as últimas ( tac inverte sua entrada, imprime a última linha como primeiro, penúltimo como segunda etc.).
O \K na expressão regular informa grep para ignorar o que veio antes do \K , para que não seja impresso ao usar -o .
Outra abordagem, mais próxima do que você tinha em mente, seria ler os arquivos de destino em um loop:
wget -qO- http://ftp.gnu.org/gnu/wget/ |tac |
grep -Pom 2 'href="\K(.+?.tar.gz)' |
while read target; do
wget http://ftp.gnu.org/gnu/wget/"$target";
done