2016-05-17 9 views
0

Ich bin hier mit einer anderen Frage über Awk.Head & Tail mit Awk in Bash-Skript

Ich muss awk Befehl innerhalb Bash-Skript mit Skript-Argumente verwenden.

Alles, was ich tun muß, ist: Kopf & Schwanz jede Datei, die arg

Beispiel in Skript gegeben: ./script.sh 5 3 Sample *

(wo Samples * Dateien sind: Sample , sampledata1, sampledata2 ....; 5 - ist für "Kopf", 3 - ist für "Schwanz").

Alles, was ich habe, ist:

#!/bin/bash 

awk -v h="$1" -v t="$2" 'NR<=h && NR>=t' "$3" 

Das aber nur für die erste Datei von Sampledaten arbeitet *!):

Wie kann ich es für jede Datei von sampledata * ??? Danke für jede Hilfe!

+2

Suche awk refs für 'FNR'. – jas

+0

Ich habe versucht, FNR == 1, nichts passiert –

+2

_FNR ist die aktuelle Datensatznummer in der aktuellen Datei. FNR wird jedes Mal erhöht, wenn ein neuer Datensatz gelesen wird. Es wird bei jedem Start einer neuen Eingabedatei auf Null zurückgesetzt._ Verwenden Sie also "FNR" anstelle von "NR", sodass die Datensatznummern bei jeder neuen Datei von 1 neu gestartet werden. – jas

Antwort

3

Wie bereits in den commants out Sie müssen FNR statt NR verwenden, aber Sie müssen auch den Rest der Argumente zu awk weitergeben müssen:

#!/bin/bash 
h=$1 
t=$2 
shift 2 # Remove first two positional variables 
awk -v h="$h" -v t="$t" 'FNR<=h && FNR>=t' "[email protected]" 

Oder mit Scheibe:

#!/bin/bash 
awk -v h="$1" -v t="$2" 'FNR<=h && FNR>=t' "${@:3}" 

, die auch mit sed geschrieben werden könnte:

sed -n "${1},${2}p" "${@:3}" 

Welcher Druck wird zwischen $1 und $2 gedruckt.

+0

@MikeJames Es wird die zwei ersten Argumente abschneiden und den Rest als separate Argumente für 'awk' senden, zB:' set a b c d; echo "$ {@: 3}" 'erweitert sich zu' echo 'c' 'd''. – andlrc

+0

Sorry, es funktioniert aber falsch, es gibt andere Zeilen aus, die nicht da sein sollen. Ich habe zwei Dateien sampledata, sampledata1, head-5, tail-3, die Ausgabe sollte 6 Zeilen, oder? Diese Variante gibt viel mehr Zeilen aus): Was kann falsch sein? –

+0

Es scheint, als ob es mehrmals durch dieselbe Datei geht. –

0

Ich nehme an, Sie wollen die ersten 5 Zeilen und letzten 3 Zeilen der Dateien. Für das Ende müssen Sie beginnen, am Ende der Datei zu zählen. Wenn Sie nur wenige Zeilen interessiert sind, können Sie es wie folgt tun (ich habe 3 und 2 verwendet)

$ awk -v h=3 -v t=2 'function pr() {for(i=j;i<j+t;i++) print p[i%t];j=0} 
        NR!=FNR && FNR==1{pr()} 
          FNR<=h; 
            {p[j]=$0;j=(j+1)%t} 
           END{pr()}' <(seq 10) <(seq 7) 
1 
2 
3 
9 
10 
1 
2 
3 
6 
7