Как мне вернуться из сценария awk обратно в командную строку?

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

{
    x=temp;
    print x;
}

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

awk -v temp=hello -f test1.awk

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

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

hello

hello

hello

hello
^C
D:\>

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

3 ответа

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

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

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

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

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

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

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

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

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

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

    C:\Users\scott> \cygwin64\bin\gawk -v temp= привет 'END {x=temp; print x;}' /dev/null
    Привет
    Разница в том, что когда вы говорите< 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 "Good bye"}'матрос Привет морякнезнакомец Привет незнакомецCtrl+D Прощай
    тогда как, если я нажмуCtrl+C,ENDкод не запускается

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


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

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

Чтобы избежать бессмысленного ввода файла, вы можете поместить команды в предложение 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
Другие вопросы по тегам