Wie komme ich von einem awk-Skript zurück zur Befehlszeile?

587
dacfer

Ich habe ein einfaches awk-Skript test1.awk:

{ x=temp; print x; } 

Wenn ich es von der Eingabeaufforderung aus mit:

awk -v temp=hello -f test1.awk 

Ich bekomme nur einen Cursor. Ich drücke Enter, es schreibt "Hallo" und gibt einen anderen Cursor, drückt Entererneut, und es schreibt erneut "Hallo" usw. Nur eine Endlosschleife erfordert die Eingabe durch den Benutzer und kommt nie zur Eingabeaufforderung zurück.

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

Wie bekomme ich "Hallo" (ohne Benutzereingaben) und stoppe dann?

0
Ihr Beispiel ist gleichzeitig komplex und trivial. Es ist komplex in dem Sinne, dass es eine Variable hat, die über '-v' gesetzt werden muss. Andernfalls führt das Programm nichts aus und kopiert diese Variable dann in eine andere Variable. Es ist trivial in dem Sinne, dass es nur den Wert dieser Variablen ausgibt. Beim Debugging / der Fehlerbehebung ist Trivial gut und komplex ist schlecht. Um zu versuchen, * etwas * (irgendetwas) zum Laufen zu bekommen, sollten Sie wahrscheinlich mit unbedeutenden Dingen wie ` `. Ein etwas weniger triviales Beispiel finden Sie in meiner Antwort. Scott vor 6 Jahren 0

3 Antworten auf die Frage

1
Lewis M

Awk liest aus stdin. Wenn Sie awk wie oben ausführen, verarbeitet das awk-Skript stdin. Sie haben es in keiner Datei zur Verarbeitung übergeben. Wenn Sie eine Datei, beispielsweise test.in, haben, können Sie Ihr awk-Programm wie folgt ausführen:

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

Das awk-Skript verarbeitet test.in und wird beendet.

Hoffe das hilft.

Danke, was muss ich in test.in setzen? dacfer vor 6 Jahren 0
Was versuchst du mit deinem awk-Skript? Lewis M vor 6 Jahren 0
Ich versuche, mit awk eine Umgebungsvariable net_args zu interpretieren: net_args = debug = (123,456), um zu sehen, ob% 1 da ist oder nicht. Wenn ja, dann beende ich das awk-Skript mit exit 1, sonst exit 0 dacfer vor 6 Jahren 0
also verwende ich: awk -v "temp =% net_args%" -v dflag =% 1 -f test.awk test.in. Ich habe Junk in test.in gestellt und es funktioniert, aber ich habe mich nur gefragt, was die Bedeutung von test.in ist. dacfer vor 6 Jahren 0
Dann kann Ihre Eingabe / dev / null sein, oder was auch immer das Äquivalent unter Windows ist. Lewis M vor 6 Jahren 0
Im Allgemeinen wird mit awk Text verarbeitet, der normalerweise von der Standardeingabe eingelesen und in die Standardausgabe geschrieben wird. Wenn Sie keine davon benötigen, können Sie / dev / null für Ihre Eingabe oder Ausgabe verwenden. Lewis M vor 6 Jahren 0
0
Matthias Gralle

Um eine sinnlose Eingabedatei zu vermeiden, können Sie die Befehle in die END-Klausel einfügen:

END { x=temp; print x; } 

Rufen Sie dann das awk-Skript mit / dev / null zur Eingabe auf, wie von Lewis M vorgeschlagen:

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

Oder gleichwertig in einer Zeile:

awk -v temp=hello 'END ' </dev/null 
0
Scott

Sie sagen, Sie möchten einige awk-Anweisungen einmal ausführen, ohne dass eine Benutzereingabe erforderlich ist. Stoppen Sie dann und kehren Sie zur Eingabeaufforderung zurück. In Ihrem Fall sprechen Sie von der Eingabeaufforderung ( cmd.exein Windows) und nicht von einer Shell (wie bash).

  1. Matthias Gralle Antwort ,

    awk -v temp = hallo 'END '</ dev / null

    funktioniert unter Unix / Linux und vielleicht sogar in einer Unix-ähnlichen Shell unter Windows, aber nicht in cmd.exe. Windows muss nicht ein /dev/null, per se.   Windows hat jedoch ein Nullgerät, das einfach aufgerufen wird NUL. (Sie können einen Doppelpunkt hinzufügen, was zu einem Ergebnis führt  NUL:, wenn Sie möchten; es ist optional. Und wie in Windows üblich, wird die Groß- und Kleinschreibung nicht beachtet, so dass Sie sagen können nul.) Also

    awk -v temp = hallo 'END '<nul
    wird wahrscheinlich funktionieren.

    Sie sagen nicht, welchen Geschmack awkSie auf Ihrem Windows-Rechner haben. Ich habe Cygwin und es stellt sich heraus, dass ich das kann

    C: \ Benutzer \ scott> \ cygwin64 \ bin \ gawk -v temp = hallo 'END '/ dev / null Hallo
    Der Unterschied ist, dass, wenn Sie sagen, der Befehlsprozessor ( in Ihrem Fall) den Dateinamen verarbeitet, aber wenn Sie das weglassen und sagen, es wird vom Programm verarbeitet. Und es stellt sich heraus, dass Cygwin-Programme das Nullgerät interpretieren , selbst wenn sie von der Eingabeaufforderung aus ausgeführt werden.< filenamecmd.exe<filename/dev/null

    Da ich nicht weiß, welchen Geschmack awkSie auf Ihrem Windows-Rechner haben, weiß ich nicht, ob dies für Sie funktioniert.

  2. Matthias war sehr nahe daran, Ihnen eine wirklich gute Antwort zu geben. Wie Lewis M erklärte, verarbeitet awk die Eingabe. Ein typisches awk-Programm sieht ungefähr so ​​aus
    BEGIN { etwas zu tun (einmal) am Anfang des Programms } { etwas für jede Eingabezeile } / foo / { etwas zu tun in jeder Zeile der Eingabe, die "foo" enthält } { etwas anderes in jeder Zeile zu tun } ︙ END { etwas (einmal) am Ende des Programms }
    wo all diese Teile optional sind. (Und wie Sie in Ihrer Frage gezeigt haben, können Codeblöcke (auch als "Aktionen" bezeichnet) in mehrere Zeilen aufgeteilt werden, und kurze Dinge können in derselben Zeile zusammengefasst werden.) Matthias 'Idee ist, Ihre Anweisungen in den ENDCode einzufügen blockieren und dann eine Null-Eingabe bereitstellen, damit awk startet, Ihre Anweisungen einmal ausführt und dann beendet.   Nicht, dass daran etwas nicht stimmt. Es stellt sich jedoch heraus, dass awk Ihre Anweisungen (einmal) ausführt, wenn Ihr Programm aus einem BEGINCodeblock und nichts anderem besteht, ohne zu versuchen, Eingaben zu lesen.   So kannst du sagen
    awk -v temp = hallo 'BEGIN '
    und müssen sich keine Gedanken über die Eingabe / Angabe von Eingaben machen.
  3. Hier ist ein Beispiel für ein triviales awk-Programm, das nicht zu trivial ist:

    awk ''

    Wenn Sie dies eingeben und dann drücken Enter, wird es sagen Hello. Wenn Sie tippen world, wird es sagen Hello world. Wenn Sie tippen Kitty, wird Hello Kitty© angezeigt . Wie Sie wissen, können Sie durch Drücken von Ctrl+ zu Ihrer Eingabeaufforderung zurückkehren C, was im Wesentlichen „Unterbrechen / Stoppen der Verarbeitung“ bedeutet. Eine "schönere" Sache ist jedoch das Drücken von Ctrl+ D, was bedeutet, "dies ist das Ende der Eingabe". Dies ist Standard bei Unix und Linux, aber ich kann Folgendes tun (wobei der bold italicText so ist, wie ich ihn eingegeben habe):

    C: \ Benutzer \ scott> \ cygwin64 \ bin \ gawk ' END '  Seemann Hallo, Matrose Fremder Hallo Fremder Ctrl+ D Auf Wiedersehen
    Wenn ich jedoch Ctrl+ drücke, läuft Cder ENDCode nicht.

    Wenn Sie etwas anderes als Cygwin verwenden, weiß ich nicht, ob dies für Sie funktioniert.


In den obigen Beispielen kann alles, was ich in einfache Anführungszeichen ( '…') setze, in eine Datei eingefügt werden, die Sie dann (wie Sie wissen) mit aufrufen . Unter Unix, Linux und Cygwin ziehe ich es vor, meine awk-Programme in Shell-Skripte zu integrieren, wie-f filename

#! / bin / sh awk ' "" $ @ "
anstatt .awkDateien zu verwenden. Damit "$@"können Sie Argumente an awk übergeben. Möglicherweise können Sie dies in einer Windows-Batchdatei mit machen $*, aber in Windows ist das nie einfach.