Nowe posty

Autor Wątek: awk/bash - prezentacja wypisanych danych  (Przeczytany 2672 razy)

cod3r

  • Gość
awk/bash - prezentacja wypisanych danych
« dnia: 2012-03-25, 16:05:11 »
Witam,
Dopiero zacząłem uczyć się awk i nie bardzo mogę poradzić sobie z jedną sprawą, pewnie banalną:).
A więc tak, potrzebuję zrobić coś takiego:

NR NAZWA PID
1  bash  12866
2  ps    14679
3  awk   14680
4  sed   14681
Chodzi głównie o spacje między kolumnami, niestety póki co dostaje wszystko zlane:
0 NAZWAPID
1 bash12866
2 ps14679
3 awk14680
4 sed14681
Mój kod wygląda jak na razie tak:
#!/bin/bash
 
b=0
c=`ps | awk '{print ($4 $1)}' |sed 's/CMD/NAZWA/'`
 
for a in $c; do
        echo $b $a " "
let "b++"
done
Próbowałem w ten sposób:
print($4" "$1)
Natomiast to zamiast znaku spacji daje mi znak nowej linii i wynik jest taki:
0 NAZWA  
1 PID  
2 bash  
3 12866  
4 zad1  
5 15028  
6 zad1  
7 15029  
8 ps  
9 15030  
10 awk  
11 15031  
12 sed  
13 15032

Offline ultr

  • Users
  • Guru
  • *****
  • Wiadomości: 1177
    • Zobacz profil
awk/bash - prezentacja wypisanych danych
« Odpowiedź #1 dnia: 2012-03-25, 17:27:44 »
#!/bin/bash

b=0
c=$( ps | awk '{print ($4"\\t"$1)}' | sed 's/CMD/NAZWA/' )

while read a; do
        x=$b;
        if [ $x -eq 0 ]; then
                x="NR"
        fi
        echo -e "$x\\t$a"
        let "b++"
done < <( echo -e "$c" )
Używając "awk '{print ($4 $1)}'" nie wstawiasz spacji. "print($4" "$1)" ją wpisuje, ale "for x in $y" rozdziela kolejne elementy na dowolnym białym znaku - w tym na tej spacji, a nie na znaku nowej linii. Dla linii użyj polecenia read jak powyżej.

Dodałem wyrównywanie tabami, choć to nie idealne rozwiązanie. Możesz pokombinować z wyrównywaniem spacjami.

Numerację można zrobić od razu w awk dodając numer linii lub w przypadku nagłówka "NR". Wtedy ten while z readem nie będzie w ogóle potrzebny.

arctgx

  • Gość
awk/bash - prezentacja wypisanych danych
« Odpowiedź #2 dnia: 2012-03-25, 18:53:10 »
Bash daje sporo możliwości (i bez seda nieraz się obejdzie), ale jak awk, to awk (a przynajmniej GNU awk):
ps | awk 'BEGIN {OFS="\\t"} {print (NR==1) ? "NR" : NR-1, (NR==1) ? "NAZWA" : $4, $1}'
- kusząca prostota wywołania :).

Warunek na pierwszą linię można wywalić jako osobne wyrażenie:
ps | awk 'BEGIN {OFS="\\t"} (NR==1) {print "NR", "NAZWA", $1}; (NR!=1) {print NR-1, $4, $1}'
albo nawet na sztywniaka dać etykiety w sekcji BEGIN:
ps | awk 'BEGIN {OFS="\\t"; print "NR", "NAZWA", "PID"}; (NR!=1) {print NR-1, $4, $1}'

cod3r

  • Gość
awk/bash - prezentacja wypisanych danych
« Odpowiedź #3 dnia: 2012-03-25, 19:39:56 »
Dzięki Wam bardzo za podpowiedzi, zaraz siadam do kodzenia :).