
У меня есть файл /tmp/a.txt
со следующим содержимым:
1
2
3
4
5
Используя AWK
, я хочу предложить пользователю указать диапазон в любом из следующих форматов и вывести соответствующие строки.
разделенные запятой
1,2,3
пространство, разделенное
1 2 3
и в диапазоне использования -
1-3
Ожидаемый результат:
1
2
3
Ниже приведен пример команды awk для захвата ввода пользователя. Что мне следует здесь указать, чтобы получить требуемый вывод?
awk 'BEGIN { printf "Enter the range: " ; getline name < "-" }{?}' /tmp/a.txt
решение1
Вы можете использовать эту awk
команду:
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
Объяснение:
printf "Enter the range: " ; getline r < "-";
скопировано из вопроса (чтобы прочитать введенные пользователем данные в переменнуюr
)split(r,a,"[ ,]")
разделите входные данные на разделители (пробел и запятая) и запишите их в массивa
.for (i in a)
Для каждой строки, которую обрабатывает awk, он проходит по массивуa
split(a[i],b,"-")
каждый элементa
снова разделяется по разделителю-
, а затем диапазон сохраняется в массивеb
.if(a[i]==NR||(b[2]!=""&&b[1]<=NR&&b[2]>=NR))
awk
если номер обрабатываемой в данный момент строки находится в массивеa
или если номер строки находится между двумя числами в массивеb
...{print}
... распечатать строку.
Вы также можете использовать комбинированный ввод, например
1-3,4 5 7-13
решение2
Не совсем понятно, хотите ли вы, чтобы номера строк ( NR
) соответствовали введенным диапазонам, или значения всей строки ( $0
), или первого поля ( $1
)... Попробуйте
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
и измените $1
на $0
или NR
.