2015-09-04 11 views
6

übergeben Ich habe eine Datei a.txt sagen und unten sind die Inhalte davon:Drucken Sie eine Liste der Felder als Variable

bob 1 100    
lincoln 2 200 
chris 3 300   

Der Inhalt der Datei durch Leerzeichen getrennt werden.

Mit awk konnte ich auf jede Spalte zugreifen. Mit folgendem Befehl drucken 1. und 3. durch Komma getrennt Spalten:

cat a.txt | awk ' { print $1","$3} ' 

und ich war erfolgreich.

Jetzt möchte ich die Kriterien dynamisch aus einem anderen Shell-Skript übergeben. Mit den Kriterien meine ich - $1","$3.

Ich versuchte den folgenden Befehl, aber es hat nicht funktioniert.

myvar="$1" 
awk -v a="$myvar" ' { print a } ' a.txt 

aber dies ist das Drucken $1 3-mal so gibt es drei Reihen in a.txt.

Wie kann ich auf diese Weise eine Liste von Feldern an awk übergeben?

+0

'„$ 1“' bedeutet, das erste Argument des Shell-Skript. Wie hast du dein Skript aufgerufen? 'Skript" 1 "'? Wenn 'a'' 1' ist, sollten Sie '$ a' – Kent

+0

" $ 1 "," $ 3 "drucken - dieser Teil muss dynamisch übergeben werden - zusammen mit den Trennzeichen. sagen wir, wenn ich 5 Spalten habe, sollte ich in der Lage sein, etwas wie $ 1 ", $ 2" - ", $ 3" ​​- "$ 4", "$ 5 dh 1 & 2, 4 & 5 getrennt durch Kommas und Ruhe durch - zu senden übergeben Sie Muster von einer anderen Datei als Argument. und awk Befehl wird auf einer anderen Datei sein –

Antwort

6

Das Problem hierbei ist, dass die $ in der Variable, die Sie awk vergangen ist wörtlich interpretiert - es kann nicht sein verwendet, um auf ein bestimmtes Feld zu verweisen.

Für ein einzelnes Feld, Sie so etwas wie diese verwenden:

awk -v field=1 '{ print $field }' file 
bob 
lincoln 
chris 

Für mehrere Felder, das ist ein wenig komplizierter:

awk -v fields="1 3" 'BEGIN{ n = split(fields,f) } 
    { for (i=1; i<=n; ++i) printf "%s%s", $f[i], (i<n?OFS:ORS) }' file 
bob 100 
lincoln 200 
chris 300 

Die Liste der Felder als String übergeben wird , die in ein Array aufgeteilt ist. Das Array wird dann durchlaufen, wobei printf verwendet wird, um jedes Feld auszugeben, gefolgt von dem Ausgabefeldtrennzeichen OFS oder dem Ausgabesatztrennzeichen ORS, abhängig davon, ob es das letzte Feld ist oder nicht. Um die Felder mit einem Komma zu trennen, können Sie -v OFS=, als Option übergeben.

+0

Ich bin froh, dass ich eine Antwort auf meine Frage gefunden habe Gibt es eine Möglichkeit, dass ich bei mehreren Dateien Delimiter zur Ausgabe hinzufügen kann –

+0

Ja, Sie können' OFS' auf etwas anderes setzen als der Standardraum mit 'awk -v OFS = 'was auch immer Sie hier wollen'. –

+0

" $ 1 "," $ 3 "- dieser Teil der tatsächlichen Frage muss dynamisch übergeben werden - zusammen mit den Trennzeichen. sagen, wenn ich habe 5 Spalten, sollte ich in der Lage sein, etwas wie $ 1 ", $ 2" - ", $ 3" ​​- "$ 4", "$ 5 dh 1 & 2, 4 & 5 getrennt durch Kommas und Ruhe durch" - ". Ich werde Muster aus einer anderen Datei als Argument übergeben. und awk Befehl wird in einer anderen Datei sein. Das erreiche ich nicht. –

3

Sie benötigen einen getrennten Zeichenfolge awk und innen awksplit an diesem Begrenzer aufzuspalten Nutzung zu übergeben.

So etwas sollte funktionieren:

awk -v search='1,3' 'BEGIN{split(search, a, ",")} 
       {f=""; for (i=1;i in a;i++) {printf "%s%s", f, $a[i]; f=OFS} print ""}' file 

Ausgang:

bob 100 
lincoln 200 
chris 300 
+0

Danke @TomFenech, ich habe es bearbeitet. Irgendwie 'Länge' funktioniert für BSD (OSX) awk. – anubhava

+1

oder erfassen Sie die Länge beim Aufteilen' len = split (...) ' – karakfa

2

Alternative zu awk-Lösung mit , die bereits Feldpositionen über kommagetrennte Liste akzeptiert.

cols="1,3"; cut -d" " -f"$cols" a.txt 

für kommagetrennte Ausgangsrohr tr ' ' ',' oder --output-delimiter="," cut-Option.

Beachten Sie, dass dies die Flexibilität Eingang als geschlossen zu spezifizieren geben oder offenen Bereich wie 1-3 oder 2-

Verwandte Themen