Sólo me pregunto cómo podemos usar awk para hacer coincidencias exactas.
por ejemplo
$ 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
Como puede ver, el comando anterior genera el número de índice de todas las líneas que contienen la cadena/número "9", ¿hay alguna manera de hacer que awk genere el número de índice solo en la cuarta línea de la salida cal anterior? ¿Puede ser una solución aún más elegante?
Estoy usando awk para obtener el nombre del día usando el comando cal. Aquí está toda la línea de código:
$ 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]}')
El problema con el código anterior es que si se encuentran varias coincidencias, obtengo varios resultados, mientras que quiero que genere solo un resultado.
¡Gracias!
Respuesta1
Podrías grep
obtener el resultado de cal
solo una línea:
$ cal 09 09 2009 | grep -E '(^9 | 9 | 9$)' | awk ...
El grep coincide con uno de:
- Un 9 seguido de un espacio al inicio de la línea.
- Un 9 rodeado de espacios
- Un espacio seguido de un 9 al final de la línea.
¿Qué te parece?
Respuesta2
Haría esto con algo como
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]}}}')"
Aquí, BEGIN
se ejecuta al inicio para configurar la days
matriz; el otro patrón se activa en las líneas 2 en adelante (omitiendo el encabezado), recorre las columnas hasta que encuentra day
y luego usa el número de columna para buscar el día de la semana. $
in awk
es el operador de referencia del campo; Así como $1
es el primer campo, $n
el campo está numerado por el valor de n
. También estoy pasando $day desde el shell al script con la asignación al comienzo de la awk
línea. NR
es el número de registro (número de línea); NF
es el número de campos en la línea. (Puede configurar RS
y FS
, respectivamente, para cambiar lo que separa los registros y los campos, respectivamente).
(La barra invertida-nuevas líneas y la nueva línea después de la tubería |
son solo para mayor claridad y para que no se desplacetambiénmucho.)
Esta vez está probado.
Respuesta3
el script en esta página hace precisamente eso
http://www.computing.net/answers/unix/find-the-day-of-week-using-awk/5243.html
Respuesta4
Prueba esto:
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)
}'
Todo en una sola línea:
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) }'
Manifestación:
$ 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
Aquí hay una mejora del guión al que se vinculó Mohamed:
cal 09 2009 | awk -v "d=9" 'NR==2 {split($0, dow)} NR == 3 {print $0, d, dow[7 - ($NF + 35 - d) % 7]}'
No hay necesidad de head
, tail
ni de un montón de if
declaraciones.