2010-01-20 7 views
2

J'ai un fichier de format:Linux texte Manipulation du fichier

<a href="http://www.wowhead.com/?search=Superior Mana Oil"> 
<a href="http://www.wowhead.com/?search=Tabard of Brute Force"> 
<a href="http://www.wowhead.com/?search=Tabard of the Wyrmrest Accord"> 
<a href="http://www.wowhead.com/?search=Tattered Hexcloth Sack"> 

je dois sélectionner le texte après le signe =, mais avant le "et imprimer à la fin de la ligne, en ajoutant de sorte qu'il devient pour exemple:

<a href="http://www.wowhead.com/?search=Superior Mana Oil">Superior Mana Oil</a> 
<a href="http://www.wowhead.com/?search=Tabard of Brute Force">Tabard of Brute Force</a> 
<a href="http://www.wowhead.com/?search=Tabard of the Wyrmrest Accord">Tabard of the Wyrmrest Accord</a> 
<a href="http://www.wowhead.com/?search=Tattered Hexcloth Sack">Tattered Hexcloth Sack</a> 

Je ne suis pas sûr de la meilleure façon de le faire via la ligne de commande linux (je suppose probablement sed/awk mais pas bien avec eux), serait idéalement comme un script que je peux nourrir le nom du fichier par exemple ./fixlink.sh brokenlinks.txt

+3

Essayez d'écrire le script et lancez-le. Quand/Si vous obtenez des erreurs, affichez-les ici et de l'aide sera disponible. "S'il vous plaît écrire mes scripts pour moi" les questions de type ne sont pas très encouragés ici. –

Répondre

3

En supposant que vous pouvez avoir un ou plus d'espace AFER <a, et zéro ou plus d'espace autour des = signes, les éléments suivants doivent travailler:

$ cat in.txt 
<a href="http://www.wowhead.com/?search=Superior Mana Oil"> 
<a href="http://www.wowhead.com/?search=Tabard of Brute Force"> 
<a href="http://www.wowhead.com/?search=Tabard of the Wyrmrest Accord"> 
<a href="http://www.wowhead.com/?search=Tattered Hexcloth Sack"> 
# 
# The command to do the substitution 
# 
$ sed -e 's#<a[ \t][ \t]*href[ \t]*=[ \t]*".*search[ \t]*=[ \t]*\([^"]*\)">#&\1</a>#' in.txt 
<a href="http://www.wowhead.com/?search=Superior Mana Oil">Superior Mana Oil</a> 
<a href="http://www.wowhead.com/?search=Tabard of Brute Force">Tabard of Brute Force</a> 
<a href="http://www.wowhead.com/?search=Tabard of the Wyrmrest Accord">Tabard of the Wyrmrest Accord</a> 
<a href="http://www.wowhead.com/?search=Tattered Hexcloth Sack">Tattered Hexcloth Sack</a> 

Si vous êtes sûr que vous ne disposez pas des espaces supplémentaires , le schéma se simplifie en:

s#<a href=".*search=\([^"]*\)">#&\1</a># 

dans sed, s suivi d'un caractère (# dans ce cas) commence substitution. Le motif à substituer est jusqu'à la deuxième apparition du même personnage. Ainsi, dans notre deuxième exemple, le modèle à substituer est: <a href=".*search=\([^"]*\)">. J'ai utilisé \([^"]*\) pour signifier, toute séquence de non " caractères, et enregistré en référence arrière \1 (la paire \(\) indique une référence arrière). Enfin, le jeton suivant délimité par # est le remplacement. & dans sed signifie "tout ce qui correspond", qui dans ce cas est la ligne entière, et \1 correspond juste au texte du lien.

Voici le motif nouveau:

's#<a[ \t][ \t]*href[ \t]*=[ \t]*".*search[ \t]*=[ \t]*\([^"]*\)">#&\1</a>#' 

et son explication:

Si vous êtes vraiment sûr qu'il y aura toujours search= suivi par le texte que vous voulez, vous pouvez faire:

$ sed -e 's#.*search=\(.*\)">#&\1</a>#' 

Espérons que h elps.

+2

Aucun downvote en raison de l'effort héroïque, mais quand une ligne de code nécessite 14 lignes d'explication, il est probablement trop intelligent pour la prochaine personne à le maintenir. –

+0

LOL @Adam: Je supposais que l'OP ne savait rien sur les expressions régulières. Cela, couplé avec un modèle «robuste» a entraîné une longue explication. Eh bien, j'ai essayé. Avec un peu de chance, il a appris * quelque chose * (s'il ne s'ennuyait pas 1/3ème de mon post!). :-) –

+0

Lorsque j'essaie d'expliquer quelque chose de technique à ce niveau de détail, je trouve habituellement que j'apprends quelque chose moi-même - donc ce n'est jamais un effort inutile. –

2
awk 'BEGIN{ FS="=" } 
{ 
    o=$NF 
    gsub(/\042>/,"",o) 
    print $0, o"</a>" 

}' file 

sortie

$ ./shell.sh 
<a href="http://www.wowhead.com/?search=Superior Mana Oil"> Superior Mana Oil</a> 
<a href="http://www.wowhead.com/?search=Tabard of Brute Force"> Tabard of Brute Force</a> 
<a href="http://www.wowhead.com/?search=Tabard of the Wyrmrest Accord"> Tabard of the Wyrmrest Accord</a> 
<a href="http://www.wowhead.com/?search=Tattered Hexcloth Sack"> Tattered Hexcloth Sack</a> 

si vous n'êtes pas bon à quelque chose, lisez les docs. C'est toujours le début de la solution. Pour en savoir plus sur awk/gawk, rendez-vous au doc.

0

alors faisons-le dans sed.

replace.sh

#!/bin/bash 
#<a href="http://www.wowhead.com/?search=Tattered Hexcloth Sack"> 
# => 
#<a href="http://www.wowhead.com/?search=Tattered Hexcloth Sack">Tattered Hexcloth Sack</a> 
sed -r -e 's|(<a href=".*search=(.*))">|\1">\2</a>|' $1 

l'entrée de.txt

0

Utilisation sed:

sed 's/\(.*search=\)\(.*\)\(".*\)/\1\2\3\2<\/a>/' brokenlinks.txt 
2

Belle awk! Mais

sed -n 's|=\([^"].*\)">|&\1</a>|p'

est plus courte et silencieusement supprimer les lignes qui ne correspondent pas.

+0

+1 pour utiliser '&'. –

Questions connexes