Bash: Gibt alle Zeichen zwischen dem n-ten Auftreten von zwei verschiedenen Zeichenfolgen in einer Zeichenfolge zurück

320
wdavro

In einem Bash-Skript (auf Ubuntu 14.04) führe ich den Befehl aus:

WP055="$(wget -qO - http://alerts.weather.gov/cap/wwaatmget.php?x=CAZ055&y=1)" 

In der WP055-Variablenzeichenfolge gibt es eine unbekannte Anzahl von '<title>' und '</ title>' Paaren. Ich muss in jedem dieser Paare nach der Zeichenfolge 'by NWS' suchen, was bedeutet, dass diese bestimmte Zeichenfolge die Start- und Endzeit der jeweiligen Wetterempfehlung enthält. Diese gefundene Zeichenfolge (alle Zeichen zwischen dem öffnenden und dem schließenden title-Tag) ist das, was ich in einer anderen Variablen erfassen möchte, damit ich es in eine index.html-Datei ablegen kann, die das Skript erstellt.

Ich hatte vor, die WP055-Variable x so oft zu durchlaufen, wie oft der Text in jedem Paar von Tags analysiert wurde, bis ich den richtigen gefunden habe.

Ich kann WP055 nicht nach 'by NWS' durchsuchen, da es in WP055 mehr als ein Vorkommen geben kann (mehrere Hinweise in der WP055-Zeichenfolge).

(Der obige Befehl wget hat definitiv eine 'by NWS'-Zeichenfolge innerhalb des 2. Titelpaares bis zum 7. März um 03:00 Uhr MESZ, wenn die aktuelle Windempfehlung aufgehoben wird.)

1
Beeindruckend. Vielen Dank @ G-Man. Ich habe mit diesem und den String-Indizes zwei volle Wochenenden zu kämpfen gehabt (und versagt). Ihre Lösung ist so viel sauberer. Ich werde das heute Abend und am kommenden Wochenende in mein Programm einarbeiten. Vielen Dank. wdavro vor 8 Jahren 0
Bitte. Nur damit Sie wissen, das System hat mir mitgeteilt, dass Sie meine Antwort akzeptiert haben, aber es hat mich nicht auf Ihren Kommentar (oben) aufmerksam gemacht, obwohl Sie "@ G-Man" sagten. Sie können eine Person nur dann auf diese Weise "pingen", wenn Sie einen Beitrag kommentieren, den er geschrieben hat, oder unter einem seiner Kommentare. Wenn Sie also jemandem etwas sagen möchten, der Ihre Frage beantwortet hat, sollten Sie die Antwort kommentieren. G-Man vor 8 Jahren 0

1 Antwort auf die Frage

0
G-Man

Ein wenig unpoliert, aber es scheint zu funktionieren:

WP055="$(wget -qO - http://alerts.weather.gov/cap/wwaatmget.php?x=CAZ055&y=1)" remainder=$ if [ "$WP055" = "$remainder" ] then echo "No title found" exit fi while true do this_title=$ if [ "$remainder" = "$this_title" ] then echo "</title> not found" exit fi if [[ "$this_title" == *"by NWS"* ]] then echo "$this_title contains \"by NWS\"" # You probably want to do something here, like return. fi new_remainder=$ if [ "$new_remainder" = "$remainder" ] then echo "No more titles" exit fi remainder=$new_remainder done 

remainder=$ist eine Form der Parametererweiterung, die ein übereinstimmendes Präfixmuster entfernt. Hier setzt es remainderan

  • Der erste Titel in der Zeichenfolge ( ohne Einleitung <title>),
  • das Nachlaufen </title>und
  • der Rest der Zeichenfolge danach (einschließlich aller nachfolgenden Titel).

Wenn "$WP055" = "$remainder", bedeutet dies, dass die Shell <title>die Zeichenfolge nicht gefunden hat.

this_title=$Ähnlich setzt this_title es $remaindersich mit dem ersten zusammen, aber nicht mit dem ersten </title>.

if [[ something1 == something2 ]]führt mit den doppelten Klammern ( [[ … ]]) und dem doppelten Gleichheitszeichen ( ==) ein Muster aus. Alles andere ist Wiederholung.

Dies kann sich bei fehlerhafter Eingabe ungewöhnlich verhalten. dh Text, wo <title>und </title>nicht in alternierenden Paaren vorkommen.