2016-03-21 5 views
1
size=$(wc -l < "$1") 
    if [ "$size" -gt 0 ] 
    then 
     tr "[:lower:]" "[:upper:]" < $1 > output 
     for ((i=1; i <= "$size"; ++i)) 
     do 
      echo "Line " $i $(head -"$i" > output | tail -1 > output) 
     done 

Hallo Leute! Ich habe ein Problem mit diesem kleinen Code. Alles funktioniert gut außer dem Kopf-Schwanz-Ding. Ich möchte nur die Zeilennummer "i" aus einer Datei anzeigen. Die Ergebnisse, die ich erhalte, sind nur die letzte Zeile ($ size).Wie wird die Pipe in einer Datei mit Head-Tail-Operation verwendet?

Ich denke, vielleicht ist es etwas falsch mit der Eingabe von Tail. Der Kopf - "$ i" geht nicht in der angegebenen Zeile. :( Irgendwelche Gedanken

Ohhhh ... Ich habe gerade realisiert:? Als Eingabe für meinen Schwanz i dem gleichen Eingang gibt für Kopf Die Lösung ist das Ergebnis von Kopf bis Schwanz zu geben, Wie kann ich das tun..? : -/

+0

Blick auf den ersten Beitrag: http://stackoverflow.com/questions/6022384/bash-tool-to-get-nth-line-from-a-file Solange es funktioniert für Die letzte Zeile muss für jede Zeile funktionieren. Die Geschwindigkeit der Ausführung beeinflusst mich nicht, ich habe kleine Dateien. Also möchte ich sed nicht benutzen. – Marko

Antwort

1

Sie müssen sich nicht umleiten output von head einzureichen.!. Andernfalls erhält die Pipe überhaupt keine Eingaben, verwenden Sie auch >>, um Ergebnisse anzuhängen, sonst überschreiben Sie die Datei mit der nächsten Iteration der Schleife. Stellen Sie jedoch sicher, dass die Ausgabedatei vor jedem neuen Aufruf des Skripts gelöscht wird. Andernfalls werden Sie einfach fortlaufend an die Ausgabedatei anhängen.

echo "Line " $i $(head -"$i" $infile | tail -1 >> output) 
+0

Was genau soll >> in diesem Fall bitte? – Marko

+0

Mit '>>' wird die Ausgabe an die Datei angehängt. Wenn also die Datei bereits existiert, fügt sie dieser Datei eine neue Zeile hinzu, wobei alles zurückgegeben wird, ohne den vorhandenen Inhalt zu löschen. '>' löscht den Inhalt der Datei, falls vorhanden, und fügt dann die neuen Zeilen hinzu. Wenn Sie also '>' in einer Schleife verwenden, erhalten Sie nur die Ausgabe der letzten Iteration. Um das zu verhindern, benutze '>>'. – Munir

+0

Ohh ... deshalb habe ich nur die letzte Zeile bekommen. Ich hab es geschafft. Vielen Dank! – Marko

0

ich glaube, du cat -n mit dem Präfix „Line“ wieder Implementierung Wenn ja, awk zur Rettung

awk '{print "Line "NR, tolower($0)}' 
+0

awk findet und ersetzt Text, ich echo nur die Nummer der Zeile ($ i) und ich versuche, die Zeile selbst auch zu echo, funktioniert aber nur für die letzte Zeile. Ich möchte die Pipe-Sache nicht mit einem anderen Befehl reparieren. – Marko

+0

Ohhhh ... ich habe gerade gemerkt: Als Eingabe für meinen Schwanz gebe ich den gleichen Input für den Kopf. Die Lösung besteht darin, dem Kopf das Ergebnis zu geben. Wie mache ich das? : -/ – Marko

+0

'awk' ersetzt keinen Text, nimmt Input und erzeugt Output. Dein Pipe-Befehl ist gebrochen, weil das nicht der richtige Zweck ist. Sie möchten '> output' aus dem ersten Teil entfernen, wo head ist. – karakfa

0

Ich habe es gemacht. : D

Der Trick ist, die Ausgabe des Kopfes auf eine andere Datei zu setzen, die die Eingabe für Schwanz sein wird, wie folgt aus:

echo "Line " $i $(head -"$i" <output>outputF | tail -1 < outputF) 

Ihre Frage hat mich anders denken. Vielen Dank!

+0

Dies ist ein wirklich ineffizienter Ansatz mit vielen unnötigen zusätzlichen Prozessen und Datei-I/O. – chepner

1

Verwenden Sie read, um eine Eingabezeile aus der Datei abzurufen.

# Since `1` is always true, essentially count up forever 
for ((i=1; 1; ++i)); do 
    # break when a read fails to read a line 
    IFS= read -r line || break 
    echo "Line $i: $(tr [:lower:] [:upper:])" 
done < "$1" > output 

Ein Standardansatz ist über die Datei iterieren und i explizit zu halten.

i=1 
while IFS= read -r line; do 
    echo "Line $i: $(tr [:lower:] [:upper:])" 
    ((i++)) 
done < "$1" > output 
+0

Tatsächlich ist der letzte Ansatz der einfachste. – Marko

Verwandte Themen