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