
Tengo un archivo /tmp/a.txt
con el siguiente contenido:
1
2
3
4
5
Usando AWK
, quiero pedirle al usuario que especifique un rango en cualquiera de los siguientes formatos e imprima las líneas coincidentes.
separado por comas
1,2,3
espacio separado
1 2 3
y dentro del alcance usando -
1-3
Rendimiento esperado:
1
2
3
A continuación se muestra el comando awk de muestra para capturar la entrada del usuario, ¿qué debo poner aquí para obtener el resultado requerido?
awk 'BEGIN { printf "Enter the range: " ; getline name < "-" }{?}' /tmp/a.txt
Respuesta1
Puedes usar este awk
comando:
awk 'BEGIN { printf "Enter the range: " ; getline r < "-"; split(r,a,"[ ,]")} \
{for (i in a){split(a[i],b,"-"); if(a[i]==NR||(b[2]!=""&&b[1]<=NR&&b[2]>=NR)){print}}}' file
Explicación:
printf "Enter the range: " ; getline r < "-";
copiado de la pregunta (para leer la entrada del usuario en la variabler
)split(r,a,"[ ,]")
divida la entrada en los delimitadores, espacio y coma y escríbalos en una matriza
.for (i in a)
Para cada línea que procesa awk, recorre la matriza
split(a[i],b,"-")
cada elementoa
se divide nuevamente en el delimitador-
y luego el rango se guarda en una matrizb
.if(a[i]==NR||(b[2]!=""&&b[1]<=NR&&b[2]>=NR))
si el número de líneaawk
que se está procesando actualmente está en una matriza
o si el número de línea está entre los dos números de una matrizb
...{print}
... imprime la línea.
También puedes usar entradas combinadas como
1-3,4 5 7-13
Respuesta2
No está del todo claro si desea que los números de línea ( NR
) coincidan con los rangos ingresados, o con los valores de toda la línea ( $0
), o con los valores del primer campo ( $1
)... Pruebe
awk '
BEGIN {printf "Enter the range: "
getline ANS < "/dev/tty"
for (n=split (ANS, T, "[ ,]"); n; n--) {for (m=split (T[n], R, "-"); m; m--) TGT[R[m]]
for (i=R[1]+1; i<R[2]; i++) TGT[i]
}
}
$1 in TGT
' file
Enter the range: 1-3
1
2
3
y cambie $1
a $0
o NR
.