2017-05-08 2 views
0

Ich habe ein Skript, das Quelldateien, die eine "TODO" Notiz in den Kommentaren enthalten durchsucht. Außerdem verwende ich eine Verkettung von grep, git blame, uniq und sort, um die Liste zu erhalten, die von der Person bestellt wurde, die den TODO-Kommentar schrieb.verschiedene Shell-Verhalten: Bash lässt Newline, zsh hält es

Folgende funktioniert gut in bash und zsh:

#!/bin/bash 

for FILE in $(grep -r -i "todo" apps/business | awk '{print $1}' | sed 's/://' | sed 's/\#//') 
do 
git blame $FILE | grep -i "todo" 
done | sort -k2 | uniq 

Jetzt möchte ich alle Einträge zählen. Anstatt den (zeitaufwendigen) grep/git blame wieder anzurufen, möchte ich alles in $MATCHES speichern, um es zu zählen, ohne es noch einmal auszuwerten.

MATCHES=$(for FILE in $(grep -r -i "todo" apps/business | awk '{print $1}' | sed 's/://' | sed 's/\#//') 
do 
    git blame $FILE | grep -i "todo" 
done | sort -k2 | uniq) 

echo $MATCHES 

Das ist, wo ich ein anderes Verhalten in bash/zsh erleben:

zsh: das gleiche wie das erste Skript Kosten (wie erwartet)

bash: Ignoriert die Zeilenumbrüche von git Schuld, legt alles auf eine Linie. wc -l zählt 1 Zeile.

Was fehlt mir hier? Warum verhält sich Bash hier anders? Und wie bekomme ich bash die Newline nicht zu ignorieren?

+1

Probieren Sie echo $ MATCHES "'. Ohne die Anführungszeichen parst bash die Variable in Wörter basierend auf dem Wert von "IFS". – ccarton

Antwort

2

zsh führt die Worttrennung nicht standardmäßig in der nicht angegebenen Parametererweiterung $MATCH durch. Verwenden Sie , und bash sollte auch funktionieren.

Beachten Sie, dass dies die falsche Möglichkeit ist, über die Ausgabe eines Befehls zu iterieren; Verwenden Sie stattdessen eine while Schleife und den Befehl read.

grep -ri "todo" apps/business | awk '{print $1}' | sed -e 's/://' -e 's/\#//' | 
    while IFS= read -r FILE; do 
    git blame "$FILE" | grep -i todo 
    done | sort -k2 | uniq 
+0

Danke, das funktioniert sehr gut. – pentix

+0

Können Sie kurz erklären, warum "for" falsch ist, während "while" mit "read" besser ist? Vielen Dank! – pentix

+1

Siehe [Bash FAQ 001] (http://mywiki.wooledge.org/BashFAQ/001) – chepner

Verwandte Themen