Mercurial reduziert die Zeilen bei der Ausgabe von Pipelines in eine einzige Zeile

354
Joe

Ich möchte nach der Ausgabe eines mercurial-Befehls (hg) sortieren. Die Ausgabe von hg logwird in eine Zeile reduziert, wenn zu einem anderen Befehl geleitet wird, aber ich möchte separate Zeilen beibehalten.

Hier ist ein Minimum reproduzierbarer Fall:

# Initial setup mkdir /tmp/hgbug; cd /tmp/hgbug; hg init;  touch README.md; hg add README.md h commit -m "initial commit"  # Bug - the echo command replaces a complex find command echo '1a\n2b\n3c\n' | xargs -I % hg log --template '%' | sort  # Actual Output # 1a2b3c  # Expected Output # 1a # 2b # 3c 

Das interessante daran ist, dass mercurial die Zeilen nicht kollabiert, wenn die Ausgabe nicht weitergeleitet oder umgeleitet wird.

echo '1a\n2b\n3c\n' | xargs -I % hg log --template '%' # Actual Output # 1a # 2b # 3c 

Wie kann ich verhindern, dass die Quecksilberlinie beim Umleiten der Ausgabe kollabiert?

Um dies zu verdeutlichen, ist hier ein vollständigeres Beispiel, in dem die Ausgabe von sowohl hgmit als auch echomit xargseiner whileSchleife verglichen wird.

#!/bin/bash cd /tmp/hgbug  echo '# hg log - xargs' echo $'1a\n2b\n3c' | xargs -I {} hg log --template "hg-{}" | sort  echo echo '# plain echo - xargs' echo $'1a\n2b\n3c' | xargs -I {} echo "echo-{}" | sort  echo echo '# hg log - while read' echo $'1a\n2b\n3c' | while read -r file; do hg log --template "hg-$file"; done | sort  echo echo '# plain echo - while read' echo $'1a\n2b\n3c' | while read -r file; do echo "echo-$file"; done | sort 

Dieses Skript gibt Folgendes aus:

# hg log - xargs hg-1ahg-2bhg-3c  # plain echo - xargs echo-1a echo-2b echo-3c  # hg log - while read hg-1ahg-2bhg-3c  # plain echo - while read echo-1a echo-2b echo-3c 
-1
`xargs` legt einen Parameter für jede aus der Eingabe extrahierte Zeile fest. Es ist Sache des Zielprogramms, zu entscheiden, wie mehrere Parameter behandelt werden sollen. Wenn Sie jeweils einen Parameter benötigen, verwenden Sie nicht `xargs`. Verwenden Sie stattdessen `find ... -exec hg log --template {} \;` oder `find ... | beim Lesen -r-Datei; do hg log --template "$ file"; done` (beachten Sie meine Verwendung und Auslassung von Angeboten). AFH vor 7 Jahren 0
Ich verstehe immer noch nicht, wo die Ausgabe zusammenbricht. "GNU xargs" mit dem Parameter "-I" impliziert "-L 1" oder eine Zeile pro Aufruf. Also gibt es 3 'hg log`-Aufrufe. Ich möchte bei `xargs` bleiben, um die Parallelitätsfunktion zu verwenden. Wenn ich statt hg echo verwende, funktioniert alles wie erwartet. Joe vor 7 Jahren 0
Ich fügte ein vollständigeres Beispiel hinzu, in dem "hg" mit "echo" verglichen wird, um das Problem zu veranschaulichen. Joe vor 7 Jahren 0
Es stellte sich heraus, dass das Lesen während des Lesens ein Hering war. Das Problem war, dass "hg log" bei der Umleitung der Ausgabe keine nachgestellten Zeilenumbrüche hinzufügt. Das Verhalten ist sinnvoll, aber überraschend, wenn versucht wird, die Unterschiede zwischen interaktiver und umgeleiteter Ausgabe herauszufinden. Joe vor 7 Jahren 0

1 Antwort auf die Frage

0
Joe

hg logfügt keinen nachgestellten Zeilenumbruch zur Ausgabe hinzu, wenn das --templateFlag gesetzt ist und der Shell-Befehl umgeleitet oder an einen anderen Befehl weitergeleitet wird.

Damit es funktioniert, müssen Sie die Zeilenvorschubzeile wie folgt der Vorlagenzeichenfolge hinzufügen:

echo '1a\n2b\n3c\n' | xargs -I % hg log --template '%\n' | sort # Output 1a 2b 3c