Sed, awk i grep pod windows, czyli perl w Windows

Czy gdy korzystasz z Windowsów, brakuje Ci narzędzi awk, sed czy grep, które udostepnia standardowo Linux (a także AIX, Solaris itd)? Jeśli tak, to masz przed sobą kilka opcji. Instalacja poszczególnych, skompilowanych binarek poszczególnych aplikacji, instalacja systemu typu Cygwin, czy też nauczenie się Powershella. Można jednak pokusić się o inne rozwiązanie, jakim jest Perl.

Żeby nie przedłużać - przy pomocy Perla, w łatwy sposób, można uzyskać te same efekty co przy pomocy grepa, seda czy awka. Rozwiązania takie są (niemal) całkowicie przenośne - perl jest dostępny domyślnie na linuxach, aixach, solarisach i penwie gdzie indziej, a na Windowsie łatwo można go zainstalować (zob. np. strawberry perl). Niemal - ponieważ - cmd i powershell różnie obsługują cudzysłowy. Poniższe przykłady zadziałają w powershellu, w którym (w stosunku do unixopodobnych) trzeba escapeować podwójne cudzysłowy (czyli - "). W przypadku cmd sprawa się komplikuje - należy pojednyncze, zewnętrzne cudzysłowy zastąpić podwójnymi i vice-versa. Niestety, takie polecenia nie zadziałają pod Unix* - trzeba będzie escapeować znaki interpretowane przez powłokę (czyli np. $).

 

1. Sed

Przy pomocy perla nałatwiej uzyskać podstawową funkcjonalność seda, czyli podstawianie wyrażeń regularnych:

sed 's/xxx/yyy/' plik.txt

Można to zrobić w następujący sposób:

 

perl -pe 's/xxx/yyy/' plik.txt

 

2. Awk

Podstawowa funkcjonalność awk to operacje wykonywane na polach, np.

awk -F: '$1 ~/^root$/' passwd.txt - wyświetla linie pliku passwd.txt (z polami separowanymi :), których pierwsze pole to dokładnie ,,root''
awk -F: 'BEGIN {x=0};{if ($1=="root") x+=1};END {print x}' passwd.txt - zlicza wystąpienia wyrażenia root w pierwszym polu pliku passwd.txt

Tą samą funkcjonalność można uzyskać przez odpowiednio:

perl -lane '@F=split(":");print $_ if ($0=~/^root$/)' passwd.txt
perl -lane 'BEGIN {$x=0};@F=split(":");$x+=1  if (@F[0]=~/^root$/);END {print $x}' passwd.txt

 

3. Grep

Wreszcie - filtrowanie linii przy pomocy grepa:

grep root passwd.txt - wyświetlające wszystkie linie zawierające root
grep -v root passwd - wszystkie linie niezawierające wyrazu root

można uzyskać odpowiednio:

perl -ne 'print if /root/' passwd.txt
perl -ne 'print if not /root/' passwd.txt

 

Podsumowanie 

Wszędzie powyżej stosowałem operacje na pliku passwd.txt. Można jednak oczywiście stosować to między procesami (tj. | ), na tyle na ile Windows pozwoli.  W powershellu będzie to:

cat passwd.txt |perl -..., a w cmd - type passwd.txt|perl -... .

 

 Więcej ciekawych perlowych jednolinijkowców można znaleźć na stronie ..... Zachęcam do jej lektury. A na razie - życzę powodzenia z poznawaniu Perla:)