AWK для печати строк, соответствующих пользовательскому вводу, введенному в определенном формате, диапазоне и т. д.

AWK для печати строк, соответствующих пользовательскому вводу, введенному в определенном формате, диапазоне и т. д.

У меня есть файл /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.

Связанный контент