m/(regex)/ in KSH/SH?

Post Reply
Message
Author
kurt

m/(regex)/ in KSH/SH?

#1 Post by kurt »

Hi!

Ich möchte mit KSH/SH gerne in einem String einen Teilstring suchen und ausgeben. Also etwa dasselbe wie

<blockquote><pre><font size="1" face="">code:</font><hr><font face="Courier New" size="2">
$string =~ m/(regex)/;
echo $1;
</font><hr></pre></blockquote>

macht. Wie kann ich das in KSH/SH machen?

Danke, kurt

Descartes

Re: m/(regex)/ in KSH/SH?

#2 Post by Descartes »

RTFM

man 1 bash

<blockquote><pre><font size="1" face="">code:</font><hr><font face="Courier New" size="2">
BASH(1) BASH(1)

NAME
bash - GNU Bourne-Again SHell

SYNOPSIS
bash [options] [file]

COPYRIGHT
Bash is Copyright (C) 1989-1999 by the Free Software Foundation, Inc.
...
EXPANSION
...
${parameter#word}
${parameter##word}
The word is expanded to produce a pattern just as in pathname
expansion. If the pattern matches the beginning of the value of
parameter, then the result of the expansion is the expanded
value of parameter with the shortest matching pattern (the ``#''
case) or the longest matching pattern (the ``##'' case) deleted.
If parameter is @ or *, the pattern removal operation is applied
to each positional parameter in turn, and the expansion is the
resultant list. If parameter is an array variable subscripted
with @ or *, the pattern removal operation is applied to each
member of the array in turn, and the expansion is the resultant
list.

${parameter%word}
${parameter%%word}
The word is expanded to produce a pattern just as in pathname
expansion. If the pattern matches a trailing portion of the
expanded value of parameter, then the result of the expansion is
the expanded value of parameter with the shortest matching pat-
tern (the ``%'' case) or the longest matching pattern (the
``%%'' case) deleted. If parameter is @ or *, the pattern
removal operation is applied to each positional parameter in
turn, and the expansion is the resultant list. If parameter is
an array variable subscripted with @ or *, the pattern removal
operation is applied to each member of the array in turn, and
the expansion is the resultant list.

${parameter/pattern/string}
${parameter//pattern/string}
The pattern is expanded to produce a pattern just as in pathname
expansion. Parameter is expanded and the longest match of pat-
tern against its value is replaced with string. In the first
form, only the first match is replaced. The second form causes
all matches of pattern to be replaced with string. If pattern
begins with #, it must match at the beginning of the expanded
value of parameter. If pattern begins with %, it must match at
the end of the expanded value of parameter. If string is null,
matches of pattern are deleted and the / following pattern may
be omitted. If parameter is @ or *, the substitution operation
is applied to each positional parameter in turn, and the expan-
sion is the resultant list. If parameter is an array variable
subscripted with @ or *, the substitution operation is applied
to each member of the array in turn, and the expansion is the
resultant list.
...
</font><hr></pre></blockquote>

Descartes

Re: m/(regex)/ in KSH/SH?

#3 Post by Descartes »

man 1 ksh

<blockquote><pre><font size="1" face="">code:</font><hr><font face="Courier New" size="2">
KSH(1) User commands KSH(1)

NAME
ksh - Public domain Korn shell

SYNOPSIS
ksh [+-abCefhikmnprsuvxX] [+-o option] [ [ -c command-string [command-
name] | -s | file ] [argument ...] ]
...
Parameters
...
${name#pattern}, ${name##pattern}
If pattern matches the beginning of the value of parameter name,
the matched text is deleted from the result of substitution. A
single # results in the shortest match, two #'s results in the
longest match.

${name%pattern}, ${name%%pattern}
Like ${..#..} substitution, but it deletes from the end of the
value.
...
File Name Patterns
A file name pattern is a word containing one or more unquoted ? or *
characters or [..] sequences. Once brace expansion has been performed,
the shell replaces file name patterns with the sorted names of all the
files that match the pattern (if no files match, the word is left
unchanged). The pattern elements have the following meaning:

? matches any single character.

* matches any sequence of characters.

[..] matches any of the characters inside the brackets. Ranges of
characters can be specified by separating two characters by a -,
e.g., [a0-9] matches the letter a or any digit. In order to
represent itself, a - must either be quoted or the first or last
character in the character list. Similarly, a ] must be quoted
or the first character in the list if it is represent itself
instead of the end of the list. Also, a ! appearing at the
start of the list has special meaning (see below), so to repre-
sent itself it must be quoted or appear later in the list.

[!..] like [..], except it matches any character not inside the brack-
ets.

*(pattern| ... |pattern)
matches any string of characters that matches zero or more occu-
rances of the specified patterns. Example: the pattern
*(foo|bar) matches the strings `', `foo', `bar', `foobarfoo',
etc..

+(pattern| ... |pattern)
matches any string of characters that matches one or more occu-
rances of the specified patterns. Example: the pattern
+(foo|bar) matches the strings `foo', `bar', `foobarfoo', etc..

?(pattern| ... |pattern)
matches the empty string or a string that matches one of the
specified patterns. Example: the pattern ?(foo|bar) only
matches the strings `', `foo' and `bar'.

@(pattern| ... |pattern)
matches a string that matches one of the specified patterns.
Example: the pattern @(foo|bar) only matches the strings `foo'
and `bar'.

!(pattern| ... |pattern)
matches any string that does not match one of the specified pat-
terns. Examples: the pattern !(foo|bar) matches all strings
except `foo' and `bar'; the pattern !(*) matches no strings; the
pattern !(?)* matches all strings (think about it).
...
</font><hr></pre></blockquote>

Jochen

Re: m/(regex)/ in KSH/SH?

#4 Post by Jochen »

Für einfache Fälle kann man auch zu expr(1) greifen. Da hat man die Basic Regexps wie gewohnt. Man darf nur nicht den Perl-Regexp-Overkill erwarten. <img src="http://www.pl-forum.de/UltraBoard/Images/Happy.gif" border="0" align="middle"> Beispiel:<pre>expr "$VAR" : '[0-9]*$'</pre>Nach stdout wird dann die Anzahl Zeichen ausgegeben, auf die der Regexp passt. Möchte man die Zeichenkette oder einen Teil davon ausgegeben bekommen, muss man mittels \<!--no-->(\<!--no-->) einen Subausdruck bilden.<pre>expr "$VAR" : '[<!--no-->-+]\<!--no-->{0,1\<!--no-->}\<!--no-->([<!--no-->0-9]\<!--no-->{1,\<!--no-->}\<!--no-->)$'</pre>Prüft, ob in VAR eine Integerzahl mit optionalem Vorzeichen steckt und gibt die Zahl ohne Vorzeichen aus.
Eine Eigenheit von expr ist, dass man sich beim Regexp immer ein "^" vorneweg denken muss; expr sieht das sozusagen immer als gesetzt an.

Ansonsten hat Descartes Recht. Mit der Parametersubstitution kann man viel erreichen, besonders wenn man in der bash mit "shopt -s extglob" das erweiterte Globbing einschaltet. Die ksh hat das per Default an. Allerdings muss man schon ein bisschen umdenken, da ${#}/${##}/${%}/${%%} den Treffer aus der Zeichenkette entfernen. Aber 4 solche Subsitutionen sind immer noch performanter als ein expr-Aufruf, weil es als externes Programm in einem eigenen Prozess gestartet wird. Der Overhead ist da vergleichsweise gross.

Zuguterletzt: Vergiss die Parametersubstitution, wenn Du nur die Bourne-Shell (sh) hast. Die kann so was nicht. Da muss man zu Tools wie expr, sed, awk, cut oder auch perl greifen.

Jochen

kurt

Re: m/(regex)/ in KSH/SH?

#5 Post by kurt »

Danke für eure Antworten. Ich habe mich mittlerweile dazu entschieden, trotzdem Perl in meinem KSH Script zu verwenden:

<blockquote><pre><font size="1" face="">code:</font><hr><font face="Courier New" size="2">
IFCONFIG=$(/sbin/ifconfig $device)
ip=$(echo $IFCONFIG |perl -ne 'm/inet addr:((\d{1,3}\.){3}\d{1,3})/; print $1')
</font><hr></pre></blockquote>

Es ist aber schön zu wissen, dass es auch Alternativen gibt.

Gruss, kurt

Descartes

Re: m/(regex)/ in KSH/SH?

#6 Post by Descartes »

<a href="http://www.dcoul.de/faq/html/1.html#1.dynip" target="_blank"><!--auto-->http://www.dcoul.de/faq/html/1.html#1.d ... <!--auto-->

<blockquote><hr>
1.8 Wie kann ich die dynamisch vergebene IP-Adresse meines Rechners herausfinden?

Dazu gibt es (mindestens) zwei Lösungen:

- Die diversen PPP-Daemonen (pppd, ipppd,...) rufen nach erfolgtem Verbindungsaufbau das Skript /etc/ppp/ip-up auf. Dieses bekommt die zugeteilte IP-Adresse als vierten Parameter übergeben. Durch Einfügen von "echo $4 > /var/run/aktuelleIP" kann man sie speichern. Fügt man zusätzlich "rm -f /var/run/aktuelleIP" in /etc/ppp/ip-down ein, kann man als Bonus durch "test -f /var/run/aktuelleIP" überprüfen, ob man online ist. Lesehinweise: pppd (8), ipppd (8)

- Die zweite Variante funktioniert mit beliebigen IP-Netzwerkinterfaces:
env LC_ALL=C /sbin/ifconfig Devicename | sed -n '/addr:/s/ [^r]*..//gp'
Devicename ist an die eigene Konfiguration anzupassen. Bei einer Modemverbindung ppp0, beim ersten ISDN-SyncPPP-Device ippp0, bei ISDN-rawIP isdn0, ...
<hr></blockquote>

kurt

Re: m/(regex)/ in KSH/SH?

#7 Post by kurt »

Danke für den Hinweis, ich muss aber noch HWaddr, Bcast und Mask auslesen. Und da ich mich mit Perl ziemlich gut auskenne, möchte ich nicht noch extra die manpage von sed lesen.

Post Reply