Noch einmal grep, awk, sed, cut und co

Hallo

Folgender Befehl ergibt folgende Ausgabe auf der Konsole:

$ mdir B: | grep free
 1 030 799 360 bytes free
Optinal kann die Ausgabe auch folgende sein:
 3 780 608 bytes free
 249 257 984 bytes free
 59 734 016 bytes free

Ich will aber nur die Anzahl Bytes z.B. 1030799360, 3780608, 249257984 oder 59734016. man grep, man cut, man awk und man sed habe ich durchgelesen und ein paar Sachen ausprobiert. Leider mit mässigem Erfolg.

$ mdir B: | grep free | grep -E -o '[0-9](0|1|2|3|4|5|6|7|8|9| )'
59
73
4
01
6

... wieso untereinander?

$ mdir B: | grep free | awk '{print $1$2$3}'
59734016

... schon besser,
könnte aber auch _awk '{print $1$2$3$4}'_ oder _awk '{print $1$2}'_ sein.

Wie geht es richtig?

Dank und Gruss
Olli

Hallo

$ mdir B: | grep free | grep -E -o ‚0-9
59
73
4
01
6

… wieso untereinander?

grep scheint hier jedes Feld aus -o „extra für sich“
zu betrachten, keine Ahnung ob man das abstellen kann
(glaube nicht).

$ mdir B: | grep free | awk ‚{print $1$2$3}‘
59734016
… schon besser,
könnte aber auch awk ‚{print $1$2$3$4}‘ oder awk
‚{print $1$2}‘
sein. Wie geht es richtig?

Das Problem hier ist, dass Du ja 1 oder 2 oder 3
oder 4 oder … Zahlenfelder haben kannst, willst
Du es *genau* machen, böte sich das „richtige Tool“ an :wink:

 $\> mdir | perl -ane 'print @F[0..$#F-2] if/free/'

wobei @F[0…$#F-2] die Elemente der „gesplitten“
Zeile ausgibt, aber eben nur 2 weniger als das Feld (F)
groß ist. Das -a als Parameter splittet die jeweilige
Zeile nach @F.

Grüße

CMБ

Hallo,

ich biete

mdir B: | grep free | perl -pe 's/[^0-9\n]//g'

Noch effizienter ginge es mit tr statt s, ich habe aber gerade keine Lust, daran herumzubasteln :wink:

Gruesse,
Moritz

Und jetzt mal ohne Perl:

[pba@voodoo /usr/home/pba]$ echo „93029 39939 599 bytes free“ | tr -d " "|tr -d „bytes free“
9302939939599
[pba@voodoo /usr/home/pba]$

Sind zwar zwei tr’s, also unelegant, aber mehr gibt es leider nicht her :frowning:

P.

Zwischenbericht
Hallo

Mit Perl scheint es zu funktionieren.
Es ist so, ich habe da ein kleines C-Programm in dem ich mit system() diese grep-, cut- und awk-Befehle ausführe, um sie dann mit einer Pipe (#include int pipe(int fd[2])) abzufangen (write(fd[1], puffer, n)). Danach wird das Resultat weiterverarbeitet. Das C-Programm soll auf UNIX (Digital) und Linux (Red Hat Enterprise) laufen. Da ich keine UNIX-Kiste habe, kann ich nicht testen ob der Befehl perl oder tr unter UNIX funktioniert. Von grep, awk und sed weiss ich es.
Ich werde mich mal noch mit diesem statt beschäftigen (habe übrigens nur stat mit einem t, ist das gemeint?).
Ach ja, ich fand das die stdlib (strchr, strcspn, strpbrk, strtok, etc.) zu mühsam ist.

Noch weitere Ideen?

Vielen Dank für die Hilfe.
Olli

PS: Siehe auch Posting weiter unter „grep und awk“.

Hallo,

Es ist so, ich habe da ein kleines C-Programm in dem ich mit
system() diese grep-, cut- und awk-Befehle ausführe,

Wieso machst du kein einfaches Shell-Skript?
Grüße,
Moritz

Und jetzt mal ohne Perl:

Was ich grundsaetzlich fuer einen guten Ansatz halte…

> [pba@voodoo /usr/home/pba]$ echo "93029 39939 599 bytes free" | tr -d " "|tr -d "bytes free"  
> 9302939939599  
> [pba@voodoo /usr/home/pba]$

Aber Du willst Dich wirklich informieren, wie tr arbeitet.

Sind zwar zwei tr’s, also unelegant, aber mehr gibt es leider
nicht her :frowning:

Ha! Du haettest das erste tr sogar weglassen koennen und das gleiche Resultat erhalten. Ein eleganter Einsatz von tr waere aber:

 $ echo "93029 39939 599 bytes free" |tr -cd '0-9\n'

Gruss vom Frank.

Hallo Olli,

Folgender Befehl ergibt folgende Ausgabe auf der Konsole:

$ mdir B: | grep free
1 030 799 360 bytes free
Ich will
aber nur die Anzahl Bytes z.B. 1030799360, 3780608, 249257984
oder 59734016. man grep, man cut, man awk und man sed habe ich
durchgelesen und ein paar Sachen ausprobiert. Leider mit
mässigem Erfolg.

Ich arbeite gerne mit grep und sed, daher diesmal eine Lösung mit sed (ging leider nicht mit ‚pre‘):

echo " 1 030 799 360 bytes free" | sed -e „s/^[^1-9]*([1-9][0-9]*) bytes free.*$/\1/“ -e „s/ //g“

Der erste s-Befehl an sed greift die Zahl raus, der zweite s-Befehl entfernt noch die Leerzeichen.

Da du das ganze in C programmierst, würde sich das auch direkt anbieten. Ist die Ausgabe vom Programm in ‚char[] buffer‘, dann hilft folgendes:

char number[MAX\_LAENGE]; /\* Da kommt die Zahl später rein \*/
{
 char\* b = buffer;
 char\* n = number;
 while (\*b != 'b') { /\* hört beim "bytes free" auf \*/ 
 if (isdigit(\*b)) { /\* übertrage nur Ziffern \*/
 \*n = \*b;
 n += 1;
 }
 }
 \*n = '\0'; /\* nicht vergessen! \*/
}

Damit kommen wir aber schon in den Bereich des C-Brettes.

Gruß
Diether

Vielen Dank!
… für die guten Inputs.

Perl, tr, grep, sed, Shell Script und sogar Vorschläge mit C. Das reicht, um mich ein Weilchen zu beschäftigen.

Grüsse
Olli