У меня есть простой сценарий awk, test1.awk:

{
    x=temp;
    print x;
}

Когда я запускаю его из командной строки с:

awk -v temp=hello -f test1.awk

Я получаю только курсор.  Я нажимаю Enter, он пишет «привет» и дает другой курсор, снова нажимаю Enter и снова пишет «привет» и т.д.  Просто идет в бесконечном цикле, требующем ввода от пользователя, и никогда не возвращается в командную строку.

D:\>awk -v temp=hello -f test1.awk

hello

hello

hello

hello
^C
D:\>

Как мне заставить его написать «привет» (не требуя ввода данных пользователем) и затем остановиться?

3 ответа3

1

Awk читает со стандартного ввода. Когда вы запускаете awk, как вы делаете выше, скрипт awk будет обрабатывать stdin. Вы не передали его ни в один файл для обработки. Если у вас есть файл, например test.in, вы можете запустить свою программу awk следующим образом:

awk -v temp=hello -f test1.awk test.in

Скрипт awk обработает test.in и завершит работу.

Надеюсь это поможет.

0

Чтобы избежать бессмысленного ввода файла, вы можете поместить команды в предложение END:

END { x=temp; print x; }

Затем вызовите сценарий awk с /dev /null для ввода, как это было предложено Льюисом М:

awk -v temp=hello -f test1.awk </dev/null

Или эквивалентно в одну строку:

awk -v temp=hello 'END {x=temp; print x;}' </dev/null
0

Вы говорите, что хотите выполнить несколько операторов awk один раз, не требуя ввода данных пользователем, а затем остановитесь и вернитесь в командную строку.  А в вашем случае вы говорите о командной строке (cmd.exe в Windows), а не об оболочке (например, bash).

  1. Ответ Матиаса Глэра,

    awk -v temp = привет 'END {x = temp; print x;} '</dev/null

    будет работать в Unix / Linux и, возможно, даже в Unix-подобной оболочке в Windows, но не в cmd.exe .  Windows не имеет /dev/null , по сути.  Но в Windows есть нулевое устройство, которое называется просто NUL . (Вы можете добавить двоеточие, в результате чего NUL: если хотите; это необязательно.  И, как это обычно бывает в Windows, это без учета регистра, так что вы можете сказать nul .)  Так

    awk -v temp = привет 'END {x = temp; print x;} '<nul
    вероятно будет работать.

    Вы не говорите, какой вкус awk вас на Windows-машине.  У меня есть Cygwin, и получается, что я могу сделать

    C:\Users\scott> \cygwin64 \bin \gawk -v temp = привет 'END {x = temp; print x;} '/dev/null hello
    Разница в том, что когда вы говорите < filename , командный процессор (в вашем случае cmd.exe ) обрабатывает имя файла, но, если вы пропустите < и говорите просто filename , программа его обрабатывает.  И оказывается, что программы Cygwin интерпретируют /dev/null как нулевое устройство, даже если они запускаются из командной строки.

    Поскольку я не знаю, какой вкус awk вас есть на вашем компьютере с Windows, я не знаю, сработает ли это для вас.

  2. Матиас подошел очень близко к тому, чтобы дать вам действительно хороший ответ.  Как объяснил Льюис М, awk обрабатывает ввод.  Типичная awk-программа выглядит примерно так
    НАЧАЛО { что-то делать (один раз) в начале программы } { что-то делать в каждой строке ввода } / foo / { что-то делать в каждой строке ввода, содержащей "foo" }} { что-то еще делать в каждой строке строка } ︙ END { что-то сделать (один раз) в конце программы }
    где все эти части являются необязательными.  (И, как вы продемонстрировали в своем вопросе, блоки кода (или действия) можно разбить на несколько строк.  И короткие вещи могут быть соединены в одну линию.)  Идея Матиаса состоит в том, чтобы поместить ваш оператор (ы) в блок кода END , а затем предоставить нулевой ввод, чтобы awk запустил, выполнил ваш оператор (ы) один раз, а затем завершил работу.  Не то чтобы с этим что-то не так. Но получается, что, если ваша программа состоит из BEGIN блок кода, и ничего больше, то AWK выполняет ваше заявление (ы) (один раз) , не пытаясь даже никакого ввода.  Так что можете сказать
    awk -v temp = привет 'BEGIN {x = temp; печатать x;} '
    и не нужно беспокоиться о предоставлении / указании каких-либо входных данных.
  3. Вот пример тривиальной программы awk, которая не слишком тривиальна:

    awk '{print "Hello", $ 0}'

    Если вы наберете это и нажмете Enter , появится сообщение Hello .  Если вы напечатаете world , он скажет Hello world .  Если вы наберете Kitty , она скажет Hello Kitty © .  Как вы знаете, вы можете вернуться к командной строке, нажав Ctrl+C , что в основном означает «прерывание / остановка обработки».  Но "приятнее" сделать это, нажав Ctrl+D , что означает "это конец ввода".  Это стандартно для Unix и Linux, но я могу сделать следующее (где я набрал bold italic ):

    C:\Users\scott> \cygwin64 \bin \gawk '{print "Hello", $ 0} END {print "До свидания"}' моряк Привет незнакомец моряк Привет незнакомец Ctrl+D До свидания
    тогда как, если я нажму Ctrl+C , код END не запустится.

    Опять же, если вы используете что-то другое, чем Cygwin, я не знаю, будет ли это работать для вас.


Во всех приведенных выше примерах все, что я помещаю между одинарными кавычками ('…'), может быть помещено в файл, который вы затем (как вы знаете) вызываете с -f filename .  В Unix, Linux и Cygwin я предпочитаю помещать свои awk-программы в сценарии оболочки, например

#!/bin/sh
awk '{print "Hello", $0}' "$@"
вместо того, чтобы использовать .awk файлы.  "$@" Позволяет передавать аргументы в awk.  Вы можете сделать это в пакетном файле Windows с помощью $* , но в Windows все не так просто.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .