AWK zum Drucken von Zeilen, die mit der Benutzereingabe in einem bestimmten Format, Bereich usw. übereinstimmen

AWK zum Drucken von Zeilen, die mit der Benutzereingabe in einem bestimmten Format, Bereich usw. übereinstimmen

Ich habe eine Datei /tmp/a.txtmit folgendem Inhalt:

1
2
3
4
5

Mithilfe von AWKmöchte ich den Benutzer auffordern, einen Bereich in einem der folgenden Formate anzugeben und die entsprechenden Zeilen auszudrucken.

Komma getrennt

1,2,3

durch Leerzeichen getrennt

1 2 3

und in Reichweite mit -

1-3

Erwartete Ausgabe:

1
2
3

Unten sehen Sie das Beispiel eines Awk-Befehls zum Erfassen von Benutzereingaben. Was muss ich hier eingeben, um die gewünschte Ausgabe zu erhalten?

 awk 'BEGIN { printf "Enter the range: " ; getline name < "-" }{?}' /tmp/a.txt

Antwort1

awkSie können diesen Befehl verwenden :

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

Erläuterung:

  • printf "Enter the range: " ; getline r < "-";aus der Frage kopiert (um die Benutzereingaben in die Variable einzulesen r)
  • split(r,a,"[ ,]")Teilen Sie die Eingabe an den Trennzeichen Leerzeichen und Komma auf und schreiben Sie sie in ein Array a.
  • for (i in a)Für jede Zeile, die awk verarbeitet, durchläuft es das Arraya
    • split(a[i],b,"-")jedes Element awird am Trennzeichen noch einmal aufgeteilt -und der Bereich anschließend im Array gespeichert b.
    • if(a[i]==NR||(b[2]!=""&&b[1]<=NR&&b[2]>=NR))awkwenn die aktuell verarbeitete Zeilennummer im Array liegt aoder wenn die Zeilennummer zwischen den beiden Zahlen im Array liegt b...
      • {print}... drucken Sie die Zeile.

Sie können auch kombinierte Eingaben verwenden wie

1-3,4 5 7-13

Antwort2

Es ist nicht ganz klar, ob die Zeilennummern ( NR) mit den eingegebenen Bereichen übereinstimmen sollen, oder mit den Werten der gesamten Zeile ( $0) oder des ersten Felds ( $1)... Versuchen Sie

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

und ändern Sie $1zu $0oder NR.

verwandte Informationen