ich frage mich nur, wie wir awk verwenden können, um exakte Übereinstimmungen zu erzielen.
für zB
$ cal 09 09 2009
September 2009
Su Mo Tu We Th Fr Sa
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
$ cal 09 09 2009 | awk '{day="9"; col=index($0,day); print col }'
17
0
0
11
20
0
8
0
Wie Sie sehen, gibt der obige Befehl die Indexnummer aller Zeilen aus, die die Zeichenfolge/Zahl „9“ enthalten. Gibt es eine Möglichkeit, dafür zu sorgen, dass awk die Indexnummer nur in der vierten Zeile der obigen Cal-Ausgabe ausgibt??? Ist das vielleicht eine noch elegantere Lösung?
Ich verwende awk, um den Tagesnamen mit dem Befehl „cal“ abzurufen. Hier ist die gesamte Codezeile:
$ dayOfWeek=$(cal $day $month $year | awk '{day='$day'; split("Sunday Monday Tuesday Wednesday Thursday Friday Saturday", array); column=index($o,day); dow=int((column+2)/3); print array[dow]}')
Das Problem mit dem obigen Code besteht darin, dass ich mehrere Ergebnisse erhalte, wenn mehrere Übereinstimmungen gefunden werden, obwohl ich nur ein Ergebnis ausgeben möchte.
Danke!
Antwort1
Sie könnten grep
die Ausgabe so gestalten cal
, dass sie nur die folgende Zeile enthält:
$ cal 09 09 2009 | grep -E '(^9 | 9 | 9$)' | awk ...
Das Grep-Tool findet eines der folgenden Ergebnisse:
- Eine 9 gefolgt von einem Leerzeichen am Zeilenanfang
- Eine 9 umgeben von Leerzeichen
- Ein Leerzeichen gefolgt von einer 9 am Ende der Zeile.
Wie funktioniert das für Sie?
Antwort2
Ich würde das mit so etwas machen wie
dayOfWeek="$(cal $month $year |
awk -v day=$day \
'BEGIN {split("Sunday Monday Tuesday Wednesday Thursday Friday Saturday", days)}
NR > 2 {for (i = 1; i <= NF; i++) {if ($i == day) {print days[i]}}}')"
Hier BEGIN
wird am Anfang ausgeführt, um das Array einzurichten days
; das andere Muster wird ab Zeile 2 ausgelöst (überspringt die Kopfzeile), durchläuft die Spalten, bis es findet day
, und verwendet dann die Spaltennummer, um den Wochentag nachzuschlagen. $
in awk
ist der Feldreferenzoperator; ebenso wie $1
das erste Feld ist, $n
ist das Feld, das durch den Wert von nummeriert wird n
. Ich übergebe auch $day von der Shell an das Skript mit der Zuweisung am Anfang der awk
Zeile. NR
ist die Datensatznummer (Zeilennummer); NF
ist die Anzahl der Felder in der Zeile. (Sie können RS
bzw. festlegen FS
, um zu ändern, was Datensätze bzw. Felder trennt.)
(Der Backslash-Newline und der Newline nach dem Pipe-Zeichen |
dienen nur der Übersichtlichkeit und verhindern, dass es scrollt.zuviel.)
Diesmal wird es getestet.
Antwort3
das Skript auf dieser Seite macht genau das
http://www.computing.net/answers/unix/find-the-day-of-week-using-awk/5243.html
Antwort4
Probieren Sie Folgendes aus:
cal 09 2009 | awk -v "num=9" '
BEGIN {
OFS="\t";
day=" ?[^0-9]" num "([^0-9]|$)"
}
NR==2 {dow = $0}
$0 ~ day {
col=match(" " $0, day);
print $0, col, substr(dow,col,2)
}'
Alles in einer Zeile:
cal 09 2009 | awk -v "num=9" 'BEGIN {OFS="\t"; day=" ?[^0-9]" num "([^0-9]|$)"} NR==2 {dow = $0} $0 ~ day {col=match(" " $0, day); print $0, col, substr(dow,col,2) }'
Demo:
$ for i in {1..30}; do cal 09 2009 | awk -v "num=$i" 'BEGIN {OFS="\t"; day=" ?[^0-9]" num "([^0-9]|$)"} NR==2 {dow = $0} $0 ~ day {col=match(" " $0, day); print $0, num, col, substr(dow,col,2) }'; done
1 2 3 4 5 1 7 Tu
1 2 3 4 5 2 10 We
1 2 3 4 5 3 13 Th
1 2 3 4 5 4 16 Fr
1 2 3 4 5 5 19 Sa
6 7 8 9 10 11 12 6 1 Su
6 7 8 9 10 11 12 7 4 Mo
6 7 8 9 10 11 12 8 7 Tu
6 7 8 9 10 11 12 9 10 We
6 7 8 9 10 11 12 10 13 Th
6 7 8 9 10 11 12 11 16 Fr
6 7 8 9 10 11 12 12 19 Sa
13 14 15 16 17 18 19 14 4 Mo
13 14 15 16 17 18 19 15 7 Tu
13 14 15 16 17 18 19 16 10 We
13 14 15 16 17 18 19 17 13 Th
13 14 15 16 17 18 19 18 16 Fr
13 14 15 16 17 18 19 19 19 Sa
20 21 22 23 24 25 26 21 4 Mo
20 21 22 23 24 25 26 22 7 Tu
20 21 22 23 24 25 26 23 10 We
20 21 22 23 24 25 26 24 13 Th
20 21 22 23 24 25 26 25 16 Fr
20 21 22 23 24 25 26 26 19 Sa
27 28 29 30 28 4 Mo
27 28 29 30 29 7 Tu
27 28 29 30 30 10 We
Hier ist eine Verbesserung des Skripts, auf das Mohamed verlinkt hat:
cal 09 2009 | awk -v "d=9" 'NR==2 {split($0, dow)} NR == 3 {print $0, d, dow[7 - ($NF + 35 - d) % 7]}'
Es besteht keine Notwendigkeit für head
oder tail
eine Reihe von if
Anweisungen.