Ich mag awk. Vor vielen Jahren habe ich damit sogar eine kleine Anwendung geschrieben. Mittlerweile verwende ich es fast nur noch, wenn es mit sed und grep alleine nur umständlich oder gar nicht möglich ist.
Natürlich bin ich entsprechend aus der Äbung gekommen.
Deshalb schreibe ich mir hier ein paar der Ein - Dreizeiler auf, damit ich es schneller wiederfinde.
Ich möchte hier nicht behaupten, das die Codeschnippsel alle auf meinem eigenen Mist gewachsen sind, wenn sich jemand erwähnt wissen möchte... nur zu, ich beiße nicht . Der Code lässt sich häufig noch verbessern, verkürzen, optimieren. Wer Bock darauf hat, kann es durchaus gerne kommentieren, ich werde die Beispiele entsprechend anpassen.
Schnipsel liest beispiel.txt und umrahmt die Zeile mit einfachen Häcken ein, gefolgt von einem Komma. Die Zeichenketten werden nach Uppercase gewandelt. Jede tausendste Zeile hat eine Sonderbehandlung. Es werden nur Zeilen übernommen, die mehr als 3 Zeichen lang sind.
$ cat beispiel.txt asdffghgh riouiou abc aD jlvlkj EERWER FgDF $ awk 'length > 3 {i+=1;if (i % 1000 ) {printf ("'\''%s'\'',\n",toupper($1))} else {printf ("'\''%s'\''\n",toupper($1))} } ' beispiel.txt
Das Ergebnis sieht also so aus:
'ASDFFGHGH',
'RIOUIOU',
'JLVLKJV',
'EERWER',
'FGDF',
Einsatzgebiet ist ein Script, welches eine excel Spalte in Häpchen für die IN Clause von Oracle SQL für den sqldeveloper wandelt.
Folgendes Beispiel ersetzt das Linecount:
#Gibt die Anzahl der Zeilen aus. wc -l beispiel.txt|cut -db -f1
# Gibt die Anzahl der Zeilen aus und ist flexibler bei der Formatierung. # die wc Lösung hat den Nachteil, das man ja immer noch ein paar führende whitespaces hat. nawk 'BEGIN { CNT=0} {CNT++} END {printf("%d",CNT)}' beispiel.txt
Update: Titel angepasst, sind ja nicht nur awk Einzeiler
Aufgabe: Gesucht wird zuverlässig der letzte des Vormonats: Randbedingung: Das Script läuft immer am ersten des Monats.
Lösung zweiteilig:
# Liefert mm YYYY, für cal input perl -e 'use POSIX; print strftime("%m %Y\n",localtime(time-(3600*24*32)))' # die 32 sind 32 Tage, damit sicher der vorletzte Monat gefunden wird.
# liefert den letzten Tag eines Monats cal 9 2012|egrep "28|29|30|31"|tail -1|awk '{ printf $NF;}' # Das ginge bestimmt eleganter, oder?
Anwendungsbeispiel
#Konkretes Anwendungsbeispiel VorletzterMonat=`perl -e 'use POSIX; print strftime("%m %Y\n",localtime(time-(3600*24*32)))'` ZDT=`cal $VorletzterMonat|egrep "28|29|30|31"|tail -1|awk '{ printf $NF;}'` ZDAT="`echo $ZDT$VorletzterMonat|sed 's/ //g'`"
Führendes Linefeed entfernen (2012-11-23)
BEISPIEL=" Bla fasel Dings DUMS "
Die Lösung mit sed sieht so aus:
echo "$BEISPIEL"|sed 'N;s/\n//' Optional nur den ersten String: echo "$BEISPIEL"|sed 'N;s/\n//'|head -1
Das entscheidene ist der Befehl N. Der sorgt dafür, das die nächste Zeile mit in den Betrachtungsbuffer des nachfolgenden subsitute Statements einbezogen wird. Denn ein Linefeed ist der Zeilentrenner und hat als solche natürlich eine Sonderbedeutung für sed.
Im konkreten Fall hatte ich eine SQL ausgabe, die ich aus bestimmten Gründen nur als sortierte Liste erhalten konnte, aber nur den ersten String zur Weiterverarbeitung brauchte. Die sqlplus Ausgabe baute mir immer ein Linefeed vorne weg.
In Script eine eingelesenes Datum in ein anderes Format wandeln
# Transfer Date in gewünschtes Format
Beispiel HIREDATE="2018-04-01" wandeln in "01-04-18"
HIREDATE=$(date --date "$HIREDATE" +"%d-%m-%y")
################
# Transfer Date in gewünschtes Format
BIRTHDATE="30.04.1990" wandeln in "30.04.90"
# Hier versagt die obige Methode, weil date das Format nicht kennt, deshalb:
BIRTHDATE=$(echo "$BIRTHDATE"|sed -r 's/(..)\.(..)\./\2\/\1\//')
# Alternative wäre sed -r 's/(..)\.(..)\.(..)/\2-\1-/'
# #BIRTHDATE=$(echo "$BIRTHDATE"|sed -r 's/(..)\.(..)\.(..)/\2-\1-/'
# Der übersichtlichkeit halber 2-Stufig
BIRTHDATE=$(date --date "$BIRTHDATE" +"%d-%m-%y")
Installierte Pakete nach Größe sortiert anzeigen
dpkg-query -Wf '${Installed-Size}\t${Package}\n' | sort -n