Utiliser sed pour append une URL au début de chaque ligne

J'ai l'URL (voir ci-dessous) d'une certaine page Web qui énumère de nombreuses versions différentes d'un logiciel.

URL=http://ftp.gnu.org/gnu/wget/ 

Le one-liner suivant m'obtient la dernière version de la balle de tar et son file de signature hors du code HTML.

 wget -qO- http://ftp.gnu.org/gnu/wget/ | grep tar | cut -d\" -f6 | tail -n4 | grep gz 

Probablement pas le plus court un liner efficace, mais bon, j'apprends et je suis ouvert pour les commentaires. Le résultat de ce qui précède est le suivant:

 wget-1.15.tar.gz wget-1.15.tar.gz.sig 

Maintenant, la prochaine étape logique (pour moi au less), est de diriger la sortie ci-dessus dans sed et append l' $URL à l'avant de chaque ligne afin que la sortie ressemble à:

 http://ftp.gnu.org/gnu/wget/wget-1.15.tar.gz http://ftp.gnu.org/gnu/wget/wget-1.15.tar.gz.sig 

Et puis je veux redirect ça dans wget pour download les files.

La question est la suivante: Comment puis-je append la valeur de la variable bash $URL à l'avant de chaque ligne de sortie en utilisant sed ? J'ai essayé ce qui suit:

 sed "s/^/$URL/" 

Mais cela ne fait que me donner l'erreur:

 sed: -e expression #1, char 11: unknown option to `s' 

Je sais aussi que le concept de base est bon, parce que quand j'utilise ce qui suit, j'obtiens de bons résultats …

 VAR="Gorauskas, " echo "Jonas" | sed "s/^/$VAR/" 

Donc, je suppose que j'ai besoin d'échapper à tout le caractère / dans la variable $URL … Suis-je sur la bonne voie?

Utilisez un séparateur différent qui ne contient aucun des caractères de la variable.

Par exemple,

 sed "s|^|$URL|" 

(Si vous utilisez / comme séparateur et que le motif ou le rlocation contient aussi / , alors vous devriez les échapper.)

Ce que vous faites jusqu'à présent peut être remplacé par un appel d' awk :

 wget ... | awk -F\" '$6 ~ "gz$" { lastline=thisline; thisline=$6;}; '\ 'END {print lastline; print thisline;}' 

Et, bien sûr, awk peut aussi append l'URL:

 awk -F\" -v baseurl="http://ftp.gnu.org/gnu/wget/" \ '$6 ~ "gz" { lastline=thisline; thisline=$6;}; '\ 'END {print baseurl lastline; print baseurl thisline;}' 

Vous pouvez utiliser l'option --base wget ici:

 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/ 

Vous pouvez également faire tout cela directement comme ceci:

 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/{} 

Cela transmet la sortie du 1er wget à xargs qui remplace la string {} par chacun des résultats de la command piped.

Et vous pouvez sauter certaines étapes d'parsing avec une certaine supercherie:

 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/{} 

Ici, nous utilisons des PCRE ( -P ) avec grep et -o afin d'imprimer seulement la partie appariée de la ligne et -m 2 pour imprimer seulement les 2 premières correspondances. L'appel tac inverse l'input de sorte que les 2 premières correspondances sont en fait les dernières ( tac inverse son input, imprime la dernière ligne comme première, avant-dernière comme seconde etc.).

Le \K dans l'expression régulière indique à grep d'ignorer ce qui a précédé le \K pour qu'il ne soit pas imprimé en utilisant -o .


Une autre approche, plus proche de ce que vous aviez en tête, serait de lire les files cibles dans une boucle:

 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