regexp für trennung von dir/filename
Hallo! Wie könnte ich eine regexp z.B. für sed formulieren um "/dirname1/dirname2/usw/filename" zu trennen in "/dirname1/dirname2/usw/" und "filename"? Danke Robert
Robert Schelander wrote:
Wie könnte ich eine regexp z.B. für sed formulieren um "/dirname1/dirname2/usw/filename" zu trennen in "/dirname1/dirname2/usw/" und "filename"?
Suchmuster: (.*/)([^/]*) Dann hast du im Replace-Muster die Backreferences \1 und \2 fuer den Pfad und den Dateinamen. Nette Programme: http://freshmeat.net/search/?q=regex -- Have fun, Peter
Moin,
* Robert Schelander
Wie könnte ich eine regexp z.B. für sed formulieren um "/dirname1/dirname2/usw/filename" zu trennen in "/dirname1/dirname2/usw/" und "filename"?
Mit basename(1) und dirname(1) klappt es nicht? Thorsten -- When a thing has been said and said well, have no scruple. Take it and copy it. - Anatole France
Hallo, On Fri, 27 Jun 2003, Robert Schelander schrieb:
Wie könnte ich eine regexp z.B. für sed formulieren um "/dirname1/dirname2/usw/filename" zu trennen in "/dirname1/dirname2/usw/" und "filename"?
Erstmal RTFM: man basename, man dirname, man sed, man awk, info gawk
Weiters kannst du's dir aussuchen:
====
file="/dirname1/dirname2/usw/filename"
basename "$file"
dirname "$file"
echo "${file##*\/}" ## [1]
echo "${file%\/*}" ## [1]
echo "$file" | sed 's/.*\/\([^/]*\)$/\1/'
echo "$file" | sed 's/\/[^/]*$//'
echo "$file" | awk '{print gensub(".*\/","","g")}' ## [2]
echo "$file" | awk '{print gensub("\/[^/]*$","","")}' ## [2]
echo "$file" | awk -F'/' '{print$NF}'
echo "$file" | awk -F'/' '{for(i=1;i
On Sam, 28 Jun 2003 at 00:40 (+0200), David Haller wrote: [...]
echo "$file" | sed 's/.*\/\([^/]*\)$/\1/' echo "$file" | sed 's/\/[^/]*$//'
echo "$file" | sed 's#.*/\([^/]*\)$#\1#' echo "$file" | sed 's#/[^/]*$##' ist IMHO übersichtlicher (nicht so viele Backslashes und man sieht besser, wo der Slash tatsächlich als Zeichen gebraucht wird) und außerdem funktioniert die dirname-Variante nicht, wenn kein Pfad existiert: jan@p4mobil:~/tmp> file=bash jan@p4mobil:~/tmp> echo "$file" | sed 's#/\[^/]*$##' bash Mir fällt im Moment auch keine sed-only-Variante ein, die das abfangen könnte. Dir? ;-) [...]
echo "$file" | awk -F'/' '{for(i=1;i
Diese Variante hat das gleiche Problem wie Dein sed oben - sie liefert ein falsches Ergebnis, wenn es keinen / in $file gibt. echo "$file" | awk -F/ '{print substr($0,length($0)-length($NF)-1);}' wäre eine Alternative. [...]
PS: ja, die AWK-Befehle sind unschoen "komprimiert"...
ACK *duck_und_weg* Jan
* Jan Trippler schrieb am 28.Jun.2003:
On Sam, 28 Jun 2003 at 00:40 (+0200), David Haller wrote:
echo "$file" | sed 's/.*\/\([^/]*\)$/\1/' echo "$file" | sed 's/\/[^/]*$//'
echo "$file" | sed 's#.*/\([^/]*\)$#\1#' echo "$file" | sed 's#/[^/]*$##'
ist IMHO übersichtlicher (nicht so viele Backslashes und man sieht besser, wo der Slash tatsächlich als Zeichen gebraucht wird) und außerdem funktioniert die dirname-Variante nicht, wenn kein Pfad existiert:
Ich wende mich mal nicht an Jan oder David, die wissen das ohnehin, sondern an den ursprünglichen Fragesteller. Um es noch mal ganz klar und deutlich zu sagen, scheint mir nämlich ein wenig untergegangen zu sein. Wenn man den Filenamen vom Pfad trennen möchte, dann verwendet man am Besten basename, es ist nämlich genau dafür gemacht. Und wenn man den reinen Pfadanteil braucht, so nimmt man dirname. Bernd -- Alle meine Signaturen sind rein zufällig und haben nichts mit dem Text oder dem Schreiber zu tun, dem ich antworte. Falls irgendwelche Unrichtigkeiten dabei sein sollten, so bedauere ich das. Es wäre nett, wenn Du mich benachrichtigen würdest. |Zufallssignatur 0
Hallo, On Sat, 28 Jun 2003, Jan Trippler schrieb:
On Sam, 28 Jun 2003 at 00:40 (+0200), David Haller wrote: [...]
echo "$file" | sed 's/.*\/\([^/]*\)$/\1/' echo "$file" | sed 's/\/[^/]*$//'
echo "$file" | sed 's#.*/\([^/]*\)$#\1#' echo "$file" | sed 's#/[^/]*$##'
ist IMHO übersichtlicher (nicht so viele Backslashes und man sieht besser, wo der Slash tatsächlich als Zeichen gebraucht wird)
Ack.
und außerdem funktioniert die dirname-Variante nicht, wenn kein Pfad existiert: jan@p4mobil:~/tmp> file=bash jan@p4mobil:~/tmp> echo "$file" | sed 's#/\[^/]*$##' ^ 's/\\//' ;) bash
Mir fällt im Moment auch keine sed-only-Variante ein, die das abfangen könnte. Dir? ;-)
Ja. *GRINS* SHELLPROMPT$ for f in /dir/file dir/file /file file; do echo "$f" | sed '/^\/[^/]*$/{s#.*#/#;b;};/\//{s#/[^/]*$##;b;};/^[^/]*$/{s#.*#.#;}'; done /dir dir /
On Sam, 28 Jun 2003 at 23:33 (+0200), David Haller wrote:
On Sat, 28 Jun 2003, Jan Trippler schrieb:
und außerdem funktioniert die dirname-Variante nicht, wenn kein Pfad existiert: jan@p4mobil:~/tmp> file=bash jan@p4mobil:~/tmp> echo "$file" | sed 's#/\[^/]*$##' ^ 's/\\//' ;)
Hach, bist Du heute wieder pingelig ;-) Funktioniert trotzdem nicht - ätsch!
Mir fällt im Moment auch keine sed-only-Variante ein, die das abfangen könnte. Dir? ;-)
Ja. *GRINS*
Na, das hat ja gedauert *fg*
SHELLPROMPT$ for f in /dir/file dir/file /file file; do echo "$f" | sed '/^\/[^/]*$/{s#.*#/#;b;};/\//{s#/[^/]*$##;b;};/^[^/]*$/{s#.*#.#;}'; done /dir dir /
^ hier hast Du 'nen Punkt unterschlagen *grummel* *tststs* - die jungen Leute heutzutage: immer gleich diesen ekligen goto ins Rennen schicken ;-) Aber Du hast mich auf Ideen gebracht. Versuch mal den hier: <schnipp> flist=" /dir/file dir/file ./dir/file ./file /file file /dir/ dir/ ./dir/ " for f in $flist; do echo "$f" echo -ne "\tDavid: " echo "$f" | sed \ '/^\/[^/]*$/{s#.*#/#;b;};/\//{s#/[^/]*$##;b;};/^[^/]*$/{s#.*#.#;}' echo -ne "\tJan : " echo "$f" | sed \ '/^[^/]*$/{s#^#./#};/^\/[^/]*$/{s#^#/#};s#/[^/]*$##' done <schnapp> Gute Nacht Jan
* On Sun, 29 Jun 2003 at 1:44 +0200, Jan Trippler wrote: [...]
SHELLPROMPT$ for f in /dir/file dir/file /file file; do echo "$f" | sed '/^\/[^/]*$/{s#.*#/#;b;};/\//{s#/[^/]*$##;b;};/^[^/]*$/{s#.*#.#;}'; done /dir dir /
^ hier hast Du 'nen Punkt unterschlagen *grummel*
Wenn da ein Punkt hingehört - David hat in einer zweiten schon gesagt, daß die erste unvollständig ist; er schickts nochmal - die zweite war genauso unvollständig - kann es sein, daß da irgendeine der beteiligten Komponenten Hickups bekommen hat, und den Punkt für das Ende der Mail hielt? /apm -- GPG welcome, request public key: mailto:adalbert+key@lopez.at
Hallo, On Sun, 29 Jun 2003, Adalbert Michelic schrieb:
* On Sun, 29 Jun 2003 at 1:44 +0200, Jan Trippler wrote: [...]
SHELLPROMPT$ for f in /dir/file dir/file /file file; do echo "$f" | sed '/^\/[^/]*$/{s#.*#/#;b;};/\//{s#/[^/]*$##;b;};/^[^/]*$/{s#.*#.#;}'; done /dir dir /
^ hier hast Du 'nen Punkt unterschlagen *grummel*
Wenn da ein Punkt hingehört - David hat in einer zweiten schon gesagt, daß die erste unvollständig ist; er schickts nochmal - die zweite war genauso unvollständig - kann es sein, daß da irgendeine der beteiligten Komponenten Hickups bekommen hat, und den Punkt für das Ende der Mail hielt?
Offenbar. Seufz. Also dritter Versuch (mit entschaerften '^.$'. ==== Ja. *GRINS* SHELLPROMPT$ for f in /dir/file dir/file /file file; do echo "$f" | sed '/^\/[^/]*$/{s#.*#/#;b;};/\//{s#/[^/]*$##;b;};/^[^/]*$/{s#.*#.#;}'; done /dir dir / . SHELLPROMPT$ Oder nochmal uebersichtlicher geschrieben: sed ' /^\/[^/]*$/ { s#.*#/#; b; }; /\// { s#/[^/]*$##; b; }; /^[^/]*$/ { s#.*#.#; }'
[...]
echo "$file" | awk -F'/' '{for(i=1;i
Diese Variante hat das gleiche Problem wie Dein sed oben - sie liefert ein falsches Ergebnis, wenn es keinen / in $file gibt.
Daran kranken uebrigens auch die "${}" shell-Konstrukte...
echo "$file" | awk -F/ '{print substr($0,length($0)-length($NF)-1);}'
wäre eine Alternative.
Nicht wirklich... $ for f in /dir/file dir/file /file file; do echo "$f" | awk -F/ '{print substr($0,length($0)-length($NF)-1);}'; done r/file r/file /file file Das entspricht also eher basename und da ist "print $NF" praktischer (das uebrigens fuer alle 4 Faelle funktioniert ;) Du wolltest vermutlich print substr($0, 0, length($0)-length($NF)-1); ^^!! verwenden, richtig? Man muesste die gleiche Fallunterscheidung wie ich oben beim sed machen, was aber kein Problem ist. awk -F'/' ' /^\/[^/]*$/ { print "/"; next; } /\// { print gensub("\/[^/]*$","",""); next; } /^[^/]*$/ { print "."; }' An der Stelle des 'print gensub ...' kann man auch eine der anderen Varianten von "dirname" in awk, die schon genannt wurden verwenden. Aber, wie Bernd schon gesagt hat, sollte man moeglichst dirname/basename verwenden.
[...]
PS: ja, die AWK-Befehle sind unschoen "komprimiert"...
ACK *duck_und_weg*
*g* -dnh ==== -- Ah. Feeding pills to cats. I believe that I am the true master of feline-pill-administering. -- Lionel im the SDM
On Son, 29 Jun 2003 at 16:00 (+0200), David Haller wrote:
On Sun, 29 Jun 2003, Adalbert Michelic schrieb:
* On Sun, 29 Jun 2003 at 1:44 +0200, Jan Trippler wrote: [...] echo "$file" | awk -F/ '{print substr($0,length($0)-length($NF)-1);}'
wäre eine Alternative.
Nicht wirklich...
$ for f in /dir/file dir/file /file file; do echo "$f" | awk -F/ '{print substr($0,length($0)-length($NF)-1);}'; done r/file r/file /file file
Das entspricht also eher basename und da ist "print $NF" praktischer (das uebrigens fuer alle 4 Faelle funktioniert ;)
Du wolltest vermutlich
print substr($0, 0, length($0)-length($NF)-1); ^^!! verwenden, richtig?
Jepp - das kommt davon, wenn man was ungetestet in die Mail schreibt, dann ein schlechtes Gewissen kriegt, es nebenan in der Shell nochmal testet und die Korrektur nicht wieder übernimmt - ein MUA ist eben ein sch... CVS ;-) [...]
Aber, wie Bernd schon gesagt hat, sollte man moeglichst dirname/basename verwenden.
ACK, aber darum gehts doch schon gar nicht mehr ;-) Jan
Hallo, On Sun, 29 Jun 2003, Jan Trippler schrieb:
On Sam, 28 Jun 2003 at 23:33 (+0200), David Haller wrote:
On Sat, 28 Jun 2003, Jan Trippler schrieb:
und außerdem funktioniert die dirname-Variante nicht, wenn kein Pfad existiert: jan@p4mobil:~/tmp> file=bash jan@p4mobil:~/tmp> echo "$file" | sed 's#/\[^/]*$##' ^ 's/\\//' ;)
Hach, bist Du heute wieder pingelig ;-) Funktioniert trotzdem nicht - ätsch!
*g*
Mir fällt im Moment auch keine sed-only-Variante ein, die das abfangen könnte. Dir? ;-)
Ja. *GRINS*
Na, das hat ja gedauert *fg*
SHELLPROMPT$ for f in /dir/file dir/file /file file; do echo "$f" | sed '/^\/[^/]*$/{s#.*#/#;b;};/\//{s#/[^/]*$##;b;};/^[^/]*$/{s#.*#.#;}'; done /dir dir /
^ hier hast Du 'nen Punkt unterschlagen *grummel*
Nicht ich, siehe nebenan ;(
*tststs* - die jungen Leute heutzutage: immer gleich diesen ekligen goto ins Rennen schicken ;-) Aber Du hast mich auf Ideen gebracht.
Versuch mal den hier: <schnipp> flist=" /dir/file dir/file ./dir/file ./file /file file /dir/ dir/ ./dir/ " for f in $flist; do echo "$f" echo -ne "\tDavid: " echo "$f" | sed \ '/^\/[^/]*$/{s#.*#/#;b;};/\//{s#/[^/]*$##;b;};/^[^/]*$/{s#.*#.#;}' echo -ne "\tJan : " echo "$f" | sed \ '/^[^/]*$/{s#^#./#};/^\/[^/]*$/{s#^#/#};s#/[^/]*$##' done <schnapp>
Da fehlen zwei ';' bei dir. Mein sed maekelt da immer: Jan : sed: -e expression #1, char 18: Unknown option to 's' *fg* Die "unkown option" ist jew. das '}'. Korrekt waere: '/^[^/]*$/{s#^#./#;};/^\/[^/]*$/{s#^#/#;};s#/[^/]*$##;' ^ ^ Ja, die Version gefaellt mir auch ;) Funktionieren tun aber dann beide identisch :) Meine hat vielleicht den "Vorteil", dass man die Einzelfaelle besser erkennt ;) Naja, "dirname" meint bei "./dir/" und "/dir/" dass "." bzw. "/" der dirname sei, unsere Versionen geben "./dir" bzw. "/dir" aus. Da muesste man also erst noch das haengende '/' wegloeschen, falls vorher ein anderes steht. Dies hier funktioniert nun komplett wie 'dirname(1)': ==== Version Jan ==== /\/[^/]\+\/$/ { s#/$##; }; /^[^/]*$/ { s#^#./#; }; /^\/[^/]*$/ { s#^#/#; }; s#/[^/]*$##; ==== ==== Version David ==== /\/[^/]\+\/$/ { s#/$##; }; /^\/[^/]*$/ { s#.*#/#; b; }; /\// { s#/[^/]*$##; b; }; /^[^/]*$/ { s#.*#.#; } ==== -dnh -- Top 100 things you don't want the sysadmin to say: 47. Say, What does "Superblock Error" mean, anyhow?
On Son, 29 Jun 2003 at 16:17 (+0200), David Haller wrote:
On Sun, 29 Jun 2003, Jan Trippler schrieb: [...]
Versuch mal den hier: [...]
Da fehlen zwei ';' bei dir. Mein sed maekelt da immer:
Jan : sed: -e expression #1, char 18: Unknown option to 's'
*fg* Die "unkown option" ist jew. das '}'.
Korrekt waere:
'/^[^/]*$/{s#^#./#;};/^\/[^/]*$/{s#^#/#;};s#/[^/]*$##;' ^ ^ [...]
Schien das gleiche *CVS*-Problem zu sein, wie in meiner anderen Mail :-( Ich hatte das Script nämlich getestet und offenbar mal wieder nicht zurückkopiert. Jan
Hallo, *ARGH* Da hat's mir die Mail verrupft... Komischerweise ist die Mail in sent-messages komplett... Also zweiter Versuch: On Sat, 28 Jun 2003, Jan Trippler schrieb:
On Sam, 28 Jun 2003 at 00:40 (+0200), David Haller wrote: [...]
echo "$file" | sed 's/.*\/\([^/]*\)$/\1/' echo "$file" | sed 's/\/[^/]*$//'
echo "$file" | sed 's#.*/\([^/]*\)$#\1#' echo "$file" | sed 's#/[^/]*$##'
ist IMHO übersichtlicher (nicht so viele Backslashes und man sieht besser, wo der Slash tatsächlich als Zeichen gebraucht wird)
Ack.
und außerdem funktioniert die dirname-Variante nicht, wenn kein Pfad existiert: jan@p4mobil:~/tmp> file=bash jan@p4mobil:~/tmp> echo "$file" | sed 's#/\[^/]*$##' ^ 's/\\//' ;) bash
Mir fällt im Moment auch keine sed-only-Variante ein, die das abfangen könnte. Dir? ;-)
Ja. *GRINS* SHELLPROMPT$ for f in /dir/file dir/file /file file; do echo "$f" | sed '/^\/[^/]*$/{s#.*#/#;b;};/\//{s#/[^/]*$##;b;};/^[^/]*$/{s#.*#.#;}'; done /dir dir /
participants (7)
-
Adalbert Michelic
-
B.Brodesser@t-online.de
-
David Haller
-
Jan.Trippler@t-online.de
-
Peter Wiersig
-
Robert Schelander
-
Thorsten Haude