2016-03-23 10 views
1

Ich bin völlig neu im Bash-Scripting. Ich versuche, ein Skript, um durch zu lesen recent_log.txt Linie Zeile zu schreiben, die den folgenden Inhalt hat:Lesen und Ausführen verschiedener Befehle basierend auf jeder Zeile der Datei in Bash Linux?

[email protected]:/var/cache/logs$ head recent_log.txt 
./calisto/tomcat6-energy/calls.log.2016-03-05 
./calisto/tomcat6-energy/calls_flush.log.2016-03-05.gz 
./calisto/tomcat6-energy/catalina.2016-03-05.log.gz 
./calisto/tomcat6-energy/energy-receive.log.2016-03-05.gz 
./calisto/tomcat6-energy/energy.log.2016-01-01.gz 
./calisto/tomcat6-energy/energy.log.2016-01-02.gz 
./calisto/tomcat6-energy/energy.log.2016-01-03.gz 
./calisto/tomcat6-energy/energy.log.2016-01-04.gz 
./calisto/tomcat6-energy/energy.log.2016-01-05.gz 
./calisto/tomcat6-energy/energy.log.2016-01-06.txt 

und dann unten für jede Zeile hängt von dem Suffix den Befehl ausführen. Die Ausgabe sollte in einer anderen Datei erfolgen. jeder Ausgang sollte 2 Zeilen Abstand zwischen ihnen haben.

zcat users_energy.log.2016-03-20.gz | head -n5 

Das ist meine Lösung so weit ist, und ich bin nicht sicher, wie ich es vollenden sollte:

RAW_LOG_DIR=/var/cache/logs/recent_log.txt 
OUTPUT_DIR=/var/cache/logs/output 

for LOG in $RAW_LOG_DIR; do 
    zcat -f ${RAW_LOG_DIR} | head -n5 > OUTPUT_DIR 
done 

Würden Sie mir zu helfen, bitte, wie kann ich unterscheiden zwischen Katze oder zcat, .. und Wie vervollständige ich meinen Code?

Antwort

3

Ich glaube, du bist für so etwas suchen:

raw_log_dir=/var/cache/logs/recent_log.txt 
output_dir=/var/cache/logs/output 
i=0 

while read -r line; do 
    ((i > 0)) && printf '\n\n' 
    i=$((i + 1)) 

    if [[ $line = *.gz ]]; then 
     zcat "$line" | head -n5 
    else 
     head -n5 "$line" 
    fi 
done < "$raw_log_dir" > "$output_dir" 

jede Zeile der Datei lesen in $raw_log_dir (immer Variablen zitieren, Leseleitungen mit while read, nicht for). Wenn die Zeile in .gz endet, verwenden Sie zcat, andernfalls verwenden Sie einfach head direkt. Leiten Sie die Ausgabe der Schleife an die andere Datei um. Beachten Sie meine Verwendung von Variablennamen in Kleinbuchstaben, was als gute Übung gilt, da Großbuchstaben mit denen der Shell kollidieren können.

Die ersten beiden Zeilen der Schleife fügen zwei Leerzeilen vor der Ausgabe für jede Zeile nach der ersten Zeile hinzu. Auf einigen Shells können Sie dies mit der Verwendung von ((i++ > 0)) && printf '\n\n' prägnanter machen, aber ++ ist keine Standardfunktion, daher ist dieser Weg portabler.

Um zu überprüfen, ob die Dateien vorhanden sein, bevor sie zu lesen versuchen, können Sie eine Zeile wie diese an der Spitze Ihrer Schleife hinzu:

[[ -f $line ]] || continue 
+0

Vielen Dank für Ihre Antwort, die ersten beiden Zeilen sollten da sein, oder? 'RAW_LOG_DIR',' OUTPUT_DIR'? Außerdem, wo kann ich 2 Zeilen als Trennzeichen zwischen jedem Ergebnis haben? oder wenn ich etwas in Ausgabe als Trennzeichen zwischen jedem Ergebnis schreiben kann? –

+0

gibt es einige Nachricht 'Kopf: kann nicht öffnen' ./cal/tom/energy.log.2016-03-22 'zum Lesen: Keine solche Datei oder Verzeichnis head: kann './cal/tom/localhost_access_log.2016 nicht öffnen -03-22.txt 'zum Lesen: Keine solche Datei oder Verzeichnis " –

+0

danke @ Tom Fenech –

0

Haben Sie das gemeint?

RAW_LOG_DIR=/var/cache/logs/recent_log.txt 
OUTPUT_DIR=/var/cache/logs/output 
FILES=`cat $RAW_LOG_DIR | xargs -r` 

for LOG in $FILES; do 
    zcat -f $LOG | head -n5 > $OUTPUT_DIR 
done 
+0

Dank für Ihre Antwort, kann u erklären, was tut 'xargs -r '? wie kann ich auch zwischen 'zcat' und' cat' unterscheiden? –

+0

'cat' wird nur verwendet, um den Inhalt der Datei zu drucken (die, soweit ich verstanden habe, die Liste der Dateinamen enthält). 'xargs' wird verwendet, um sie in eine einzelne Zeile zu setzen, um leicht durch' for' geparst zu werden. – Claudio

Verwandte Themen