sed: alles in spitzen Klammern '<xxxx>' herausnehmen
Es soll aus einer sehr langen Zeile alle Vorkommen von <beliebiger Text> gelöscht werden. Der Text dazwischen soll ausgegeben werden. Bsp: aus <xxxxxx> diesen Text <yyyyyy> ausgeben <zzzzzz> soll 'diesen Text ausgeben' werden. Mit: echo <xxxxxx> diesen Text <yyyyyy> ausgeben <zzzzzz> | sed 's/<.*>//g' werde ich aber leider nicht glücklich. Es wird das erste '<' und letzte '>' im String gewählt, die Ausgabe ist leer. Wie lösche ich nur die kleinen Einheiten zwischen < und >? BTW wozu? - Ich will in OpenOffice-Dokumenten Volltextsuche mit grep betreiben. Nach einem unzip text.sxw steht ein content.xml zur Verfügung mit vielen Formatierungsanweisungen zwischen den <..> - und die will ich weg haben. Oder geht es eleganter, mit XSLT habe ich so in Erinnerung? danke schonmal Ekkard
Ekkard Gerlach
Es soll aus einer sehr langen Zeile alle Vorkommen von <beliebiger Text> gelöscht werden. Der Text dazwischen soll ausgegeben werden.
Bsp: aus <xxxxxx> diesen Text <yyyyyy> ausgeben <zzzzzz> soll 'diesen Text ausgeben' werden.
Mit: echo <xxxxxx> diesen Text <yyyyyy> ausgeben <zzzzzz> | sed 's/<.*>//g'
werde ich aber leider nicht glücklich. Es wird das erste '<' und letzte '>' im String gewählt, die Ausgabe ist leer. Wie lösche ich nur die kleinen Einheiten zwischen < und >?
das folgende tut's:
echo "<xxxxxx> diesen Text <yyyyyy> ausgeben <zzzzzz>" |
sed -e 's/<[^>]*>//g'
----------------^^^^-------------- alles ohne >
allerdings geht das schief, wenn es geschachtelte Tags gibt:
Hallo auch, Am Montag, 26. April 2004 21:42 schrieb Ekkard Gerlach:
Es soll aus einer sehr langen Zeile alle Vorkommen von <beliebiger Text> gelöscht werden. Der Text dazwischen soll ausgegeben werden.
Bsp: aus <xxxxxx> diesen Text <yyyyyy> ausgeben <zzzzzz> soll 'diesen Text ausgeben' werden.
Mit: echo <xxxxxx> diesen Text <yyyyyy> ausgeben <zzzzzz>
| sed 's/<.*>//g'
werde ich aber leider nicht glücklich. Es wird das erste '<' und letzte '>' im String gewählt, die Ausgabe ist leer. Wie lösche ich nur die kleinen Einheiten zwischen < und >?
BTW wozu? - Ich will in OpenOffice-Dokumenten Volltextsuche mit grep betreiben. Nach einem unzip text.sxw steht ein content.xml zur Verfügung mit vielen Formatierungsanweisungen zwischen den <..> - und die will ich weg haben. Oder geht es eleganter, mit XSLT habe ich so in Erinnerung?
Vorwarnung, ich bin eigentlich kein Scripter....aber versuch mal das: ############################# #! /bin/bash a='<' b='>' c='[^<]' i='1' while [ $i -lt 10 ]; do str=$a$c$b a=$a$c /usr/bin/sed s/$str//g /test/daten i=$[$i+1] done ############################# Nach meinen kleinen Tests klappts, wenn ich nix übersehen hab. Mußt die while-Schleife nur groß genug machen, das alle <..> erfasst werden. Bernd -- [Zufallssig 4] One OS to rule them all, one OS to find them. One OS to bring them all, and in the darkness bind them In the land of Redmond, where the shadows lie.
Hi On Monday 26 April 2004 21:42, Ekkard Gerlach wrote:
Es soll aus einer sehr langen Zeile alle Vorkommen von <beliebiger Text> gelöscht werden. Der Text dazwischen soll ausgegeben werden.
Bsp: aus <xxxxxx> diesen Text <yyyyyy> ausgeben <zzzzzz> soll 'diesen Text ausgeben' werden.
Mit: echo <xxxxxx> diesen Text <yyyyyy> ausgeben <zzzzzz>
| sed 's/<.*>//g'
werde ich aber leider nicht glücklich. Es wird das erste '<' und letzte '>' im String gewählt, die Ausgabe ist leer. Erklärung: * ist greedy (dt. gierig). Das nimmt sich erstmal alles bis zum Ende des Strings. Erst dann wird von hinten Zeichen für Zeichen "weggenommen" bis der Rest der regex passt.
Wie lösche ich nur die kleinen Einheiten zwischen < und >? Matche nicht auf jedes beliebige Zeichen mit "." sondern auf alles außer ">" mit "[^>]" (quoten im normalen Sprachgebrauch ist auch nicht leicht :-) ).
~>echo "<xxxxxx> diesen Text <yyyyyy> ausgeben <zzzzzz>"| sed 's/<[^>]*>//g' diesen Text ausgeben Das ist von den Leerzeichen her natürlich nicht besonders toll. Wenn nach jeder ">" ein " " folgt, dann geht ein "sed 's/<[^>]*> //g'" Sonst müssen mit einer weiteren sed-Zeile noch die doppelten Leerzeichen durch einfache ersetzt werden. mfg Axel
* Axel Heinrici schrieb:
~>echo "<xxxxxx> diesen Text <yyyyyy> ausgeben <zzzzzz>"| sed=20 's/<[^>]*>//g' diesen Text ausgeben=20
Das ist von den Leerzeichen her nat=FCrlich nicht besonders toll. Wenn=20
für meinen Zweck ist das ideal. Es geht nur um Textsuche innerhalb von OpenOffice-Dokumenten. Wieviele Leerzeichen dann übrig bleiben ist wurscht. Es kann übrigens auch so sein: <x x xxxx>diesen Text <yyyyy y > ausgeben<zsdz zzzz > Dann fischt die sed-Variante natürlich das richtige weg, der Vorschlag mit awk geht glaube ich nicht, weil der auf der feste Strukturen mit den Leerzeichen basiert. Danke an alle. Wer will, hier das Skript zur Suche in OpenOffice-Dokumenten: #!/bin/sh # # Skript Volltextsuche in OpenOffice Dokumenten # Name: oo-search # Aufruf: Parameter 1: Dateiname , Parameter 2: Suchtext (.. normalerweise umgekehrt) # # Volltext-Suche in *.sxw-Texten # # Rekursive Suche: # find -iname "*.sxw" -exec /usr/local/bin/oo-search {} "Toshiba Satellite" \; | more # lll=`pwd` UNZIP_DIR=/tmp/~oo-unzip test -d $UNZIP_DIR || mkdir $UNZIP_DIR chmod +w $UNZIP_DIR/* rm -R $UNZIP_DIR/* echo "===================== $1 ================" cp $1 $UNZIP_DIR cd $UNZIP_DIR unzip -o `basename $1` 2>&1 >>/dev/null /usr/local/bin/gf "$2" content.xml -i | sed -e 's/<[^>]*>//g' cd $lll Ekkard
Hallo, Am Wed, 28 Apr 2004, Ekkard Gerlach schrieb:
# Aufruf: Parameter 1: Dateiname , Parameter 2: Suchtext (.. normalerweise umgekehrt)
Wuerde ich auch umstellen...
lll=`pwd` ^^^ Uh? Aussagekraeftige Variablennamen sind die halbe Miete.
pwdp="`pwd -P`" ## die "" falls ein Leerzeichen im Pfad vorkommt!
UNZIP_DIR=/tmp/~oo-unzip test -d $UNZIP_DIR || mkdir $UNZIP_DIR chmod +w $UNZIP_DIR/* rm -R $UNZIP_DIR/*
*GRRRRRRRRRRRR* Bitte arbeite hier mit mktemp!!! UNZIP_DIR="`mktemp -d /tmp/oo-unzip.$$.XXXXXX`" (den Rest kannst du dir sparen, s.u.)
echo "===================== $1 ================" cp $1 $UNZIP_DIR ^^ *PARDAUZ*
Hier faellst du schonmal ordentlich auf die Fresse, wenn $1 Leerzeichen enthaelt, was gerade bei "Office"-Dokumenten ja geruechtehalber durchaus oefter mal vorkommen kann...
cd $UNZIP_DIR unzip -o `basename $1` 2>&1 >>/dev/null
Dito.
/usr/local/bin/gf "$2" content.xml -i | sed -e 's/<[^>]*>//g' cd $lll
Hier gilt praktisch o.g. erneut... ==== UNGETESTET!!! ==== #!/bin/sh # Achtung: Parameter vertauscht: $0 Suchtext Datei(en)... UNZIP_DIR="`mktemp -d /tmp/oo-unzip.$$.XXXXXX`" PATTERN="$1" shift trap 'rm -rf "$UNZIP_DIR"' 1 2 3 4 6 13 14 15 EXIT while test $# -gt 0 do echo "searching in '$1':" cp "$1" "$UNZIP_DIR" ### [1] pushd "$UNZIP_DIR" unzip -o "`basename \"$1\"` content.xml 2>&1 >/dev/null gf "$PATTERN" content.xml -i | sed -e 's/<[^>]*>//g' ### [2] rm -f content.xml popd shift done ==== -dnh [1] ich bin zu faul, hier jetzt etwas, das absolute und relative Dateinamen beruecksichtigt hinzuschreibseln... [2] 'gf' muss im PATH sein, was bei /usr/local/bin normalerweise der Fall ist, sonst muesste man auch den Rest (mktemp, cp, unzip, usw.) mit absoluten Pfaden aufrufen. Ggfs. macht man halt ein: GF="/usr/local/bin/gf" ... $GF "$1" content.xml draus... -- If you haven't got time to RTFM, you haven't got time to whine on this mailing list.
participants (5)
-
Axel Heinrici
-
Bernd Tannenbaum
-
David Haller
-
Dr. Jürgen Vollmer
-
Ekkard Gerlach