
Ich habe eine Datei /tmp/a.txt
mit folgendem Inhalt:
1
2
3
4
5
Mithilfe von AWK
mö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
awk
Sie 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 einzulesenr
)split(r,a,"[ ,]")
Teilen Sie die Eingabe an den Trennzeichen Leerzeichen und Komma auf und schreiben Sie sie in ein Arraya
.for (i in a)
Für jede Zeile, die awk verarbeitet, durchläuft es das Arraya
split(a[i],b,"-")
jedes Elementa
wird am Trennzeichen noch einmal aufgeteilt-
und der Bereich anschließend im Array gespeichertb
.if(a[i]==NR||(b[2]!=""&&b[1]<=NR&&b[2]>=NR))
awk
wenn die aktuell verarbeitete Zeilennummer im Array liegta
oder wenn die Zeilennummer zwischen den beiden Zahlen im Array liegtb
...{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 $1
zu $0
oder NR
.