Ваш сценарий повторяет печать, потому что awk получает две строки от egrep. Но это уже было рассмотрено в других ответах.
Я хочу объяснить какой-нибудь альтернативный способ решения проблемы, короче и проще.
Программа cal могла бы печатать неделю, начинающуюся с понедельника (что упрощает математические вычисления), когда вызывается как этот cal -NMC month year
. Используя это:
#!/bin/bash
lastday(){
printf 'Last Working Date of %s/%s = ' "$1" "$2";
cal -NMC "$1" "$2" | awk '
/[0-9]+/{val=$( NF>5?5:NF )}
END{ print val }'
}
mon="$1"
year="$2"
lastday "$mon" "$year"
Описание:
/ [0-9] + /
Выберите строки с числами (избегайте пустой строки).
NF> 5? 5: NF
Math: Если больше полей, чем 5, результат 5, иначе NF.
{val = $ (...)}
Выберите значение поля.
END {print val} '
Распечатать только значение последней строки (строки с числами).
Назовите это так:
$ ./test.sh 4 2015
Last Working Date of 4/2015 = 30
$ ./test.sh 5 2015
Last Working Date of 5/2015 = 29
$ ./test.sh 7 2015
Last Working Date of 7/2015 = 31
$ ./test.sh 1 2015
Last Working Date of 1/2015 = 30
$ ./test.sh 9 2015
Last Working Date of 9/2015 = 30
$
Dado que el archivo tiene una estructura simple con registros fácilmente distinguibles, y desea el valor en uno de estos, puede ser más fácil de usarawk
:
awk '/^Mødt ind:/ { print $NF }' file
El /^Mødt ind:/
significa que el siguiente bloque se activará para cada línea que comience con el texto Mødt ind:
. El bloque imprime $NF
, que es el valor del último campo en la línea (NF
, es el número de campo del último campo, y poner $
delante le da el valor de ese campo ).
Con estándarsed
:
sed -n 's/^Mødt ind: \(.*\)/\1/p' file
Esto hace la misma coincidencia de la línea que awk
, pero reemplaza el contenido de la línea con lo que viene después de los dos puntos y el espacio. La salida normal se desactiva con -n
y solo se emiten las líneas modificadas por la expresión.
Seguiría optando por la solución awk
ya que es más legible y más fácil de entender/modificar.
sed
solo puede manejar esto, como ya habrás adivinado:
sed 's/.*ind:\ \(.*\)/\1/;tx;d;:x'
Es una búsqueda -y -operación de reemplazo:
.*ind:\ \(.*\)
busca líneas que comiencen con cualquier carácter, seguido deind:
(el espacio se escapa ). El \(.*\)
se usa para "coincidir" con el resto de la línea y se almacena en la primera coincidencia, por lo que toda la línea se reemplaza por:\1
. El ;tx;d;:x
funciona así:tx
se ramifica para etiquetar x si la sustitución fue exitosa, d
elimina la línea, :x
es un marcador para la etiqueta x.