
Eu tenho um arquivo /tmp/a.txt
com o seguinte conteúdo:
1
2
3
4
5
Usando AWK
, desejo solicitar ao usuário que especifique um intervalo em qualquer um dos seguintes formatos e imprima as linhas correspondentes.
separados por vírgula
1,2,3
espaço separado
1 2 3
e no alcance usando -
1-3
Resultado esperado:
1
2
3
Abaixo está o exemplo de comando awk para capturar a entrada do usuário, o que devo colocar aqui para obter a saída necessária.
awk 'BEGIN { printf "Enter the range: " ; getline name < "-" }{?}' /tmp/a.txt
Responder1
Você pode 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
Explicação:
printf "Enter the range: " ; getline r < "-";
copiado da pergunta (para ler a entrada do usuário na variávelr
)split(r,a,"[ ,]")
divida a entrada nos delimitadores espaço e vírgula e escreva-os em arraya
.for (i in a)
Para cada linha de processo do awk, ele percorre o arraya
split(a[i],b,"-")
cada elementoa
é dividido novamente no delimitador-
e o intervalo é então salvo em arrayb
.if(a[i]==NR||(b[2]!=""&&b[1]<=NR&&b[2]>=NR))
se o número da linhaawk
que está sendo processado atualmente estiver na matriza
ou se o número da linha estiver entre os dois números na matrizb
...{print}
... imprima a linha.
Você também pode usar entradas combinadas como
1-3,4 5 7-13
Responder2
Não está muito claro se você deseja que os números da linha ( NR
) correspondam aos intervalos inseridos, ou aos valores da linha inteira ( $0
) ou do primeiro campo ( $1
) ... Tente
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
e mude $1
para $0
ou NR
.