Bash 4.2 unter CentOS 6.5:
In meinem habe ~/.bash_profile
ich eine Reihe von Aliasen, darunter:
alias grep='grep -n --color=always'
damit ich beim laufen automatisch farbmarkierungen und zeilennummern drucken kann grep
. Wenn ich Folgendes ausführe, funktioniert die Hervorhebung wie erwartet:
$ grep -Re 'regex_here' *.py
Als ich dies jedoch kürzlich ausführte:
$ find . -name '*.py' | xargs grep -E 'regex_here'
Die Ergebnisse wurden nicht hervorgehoben und die Zeilennummern wurden nicht gedruckt, sodass ich zurückgehen und -n --color=always
den grep
Befehl explizit ergänzen musste .
- Liest
xargs
nicht Aliase in der Umgebung? - Wenn nicht, gibt es eine Möglichkeit, dies zu erreichen?
xargs
Befehl manuell erweitern . Ich versuche herauszufinden, ob es eine Möglichkeit gibt, von der aus ich meinen Alias direkt anrufen kannxargs
.export GREP_OPTIONS='-n --color=always'
vor Ihrem xargs-Befehl versucht ?.bash_profile
. Fühlen Sie sich frei, eine Antwort zu schreiben ...Antworten:
Ein Alias befindet sich innerhalb der Shell, in der er definiert ist. Es ist für andere Prozesse nicht sichtbar. Gleiches gilt für Shell-Funktionen.
xargs
ist eine separate Anwendung, die keine Shell ist und daher kein Konzept für Aliase oder Funktionen hat.Sie können dafür sorgen, dass XARGs eine Shell aufrufen, anstatt sie
grep
direkt aufzurufen . Es reicht jedoch nicht aus, nur eine Shell aufzurufen, sondern Sie müssen auch den Alias in dieser Shell definieren. Wenn der Alias in Ihrem Namen definiert ist.bashrc
, können Sie diese Datei als Quelle verwenden. Dies funktioniert jedoch möglicherweise nicht, wenn Sie.bashrc
andere Aufgaben ausführen, die in einer nicht interaktiven Shell keinen Sinn ergeben.Achten Sie beim Eingeben des regulären Ausdrucks auf die Feinheiten des verschachtelten Zitierens. Sie können Ihr Leben vereinfachen, indem Sie den regulären Ausdruck als Parameter an die Shell übergeben.
Sie können die Alias-Suche explizit durchführen. Dann
xargs
werde ich sehengrep -n --color=always
.In zsh:
Beachten Sie übrigens, dass
find … | xargs …
bei Dateinamen, die (unter anderem) Leerzeichen enthalten , Brüche auftreten . Sie können dieses Problem beheben, indem Sie in durch Nullen getrennte Datensätze wechseln:oder mit
-exec
:Anstatt anzurufen
find
, können Sie alles komplett in der Shell erledigen. Das Glob-Muster**/
durchläuft Verzeichnisse rekursiv. In Bash müssen Sie zuerst ausführenshopt -s globstar
, um dieses Glob-Muster zu aktivieren.Dies hat einige Einschränkungen:
**/
werden symbolische Verknüpfungen zu Verzeichnissen erstellt.Ein anderer Ansatz ist die Verwendung der Prozesssubstitution, wie von Marius Matutiae vorgeschlagen .
Dies ist nützlich, wenn dies
**/
nicht zutrifft: für komplexefind
Ausdrücke oder in Bash ≤4.2, wenn Sie nicht unter symbolischen Links rekursiv arbeiten möchten. Beachten Sie, dass dies bei Dateinamen mit Leerzeichen abbricht. Ein Workaround ist das SetzenIFS
und Deaktivieren von Globbing , aber es wird langsam etwas komplexer:quelle
Verwenden
alias xargs='xargs '
quelle
sudo
…Bitte nehmen Sie dies als Demonstration eines anderen Ansatzes, den ich in der zugehörigen SO-Frage nicht finden kann :
Sie können eine Wrapper-Funktion schreiben, bei
xargs
der überprüft wird, ob das erste Argument ein Alias ist, und wenn ja, erweitern Sie es entsprechend.Hier ist ein Code, der genau das tut, aber leider die Z-Shell benötigt und daher nicht 1: 1 mit bash läuft (und ehrlich gesagt bin ich es nicht gewohnt, genug zu bash , um es zu portieren):
Beweis, dass es funktioniert:
quelle
Eine einfachere und elegantere Lösung ist die Verwendung der Prozesssubstitution :
Es wird keine neue Shell erstellt, wie dies bei der Pipe der Fall ist. Dies bedeutet, dass Sie sich noch in Ihrer ursprünglichen Shell befinden, in der der Alias definiert ist, und dass die Ausgabe genau Ihren Wünschen entspricht.
Achten Sie nur darauf, dass zwischen Umleitung und Klammer kein Leerzeichen bleibt, da sonst Bash einen Fehler auslöst. Nach meinem besten Wissen wird die Prozessersetzung von Bash, Zsh, Ksh {88,93}, aber nicht von pdksh unterstützt (mir wurde gesagt, dass dies noch nicht geschehen sollte ).
quelle
find
Befehle, obwohl Sie darauf achten müssen, dass sie in Leerzeichen unterbrochen wird und nicht so einfach behoben werdenfind | xargs
kann (durch Umschalten auf-print0
und-0
oder Verwenden von-exec
). Gegebenenfalls**/
ist einfacher und robuster.grep liest eine Reihe von Standardoptionen aus der Umgebungsvariablen GREP_OPTIONS. Wenn Sie setzen werden
In Ihrer .bashrc-Datei wird die Variable dann an Subshells weitergeleitet und Sie erhalten die erwarteten Ergebnisse.
quelle
--line-number
oder--color=always
inGREP_OPTIONS
es sei denn , es ist nur für einen Befehl, dies wird eine Menge von Skripten zu brechen.--color=auto
Es ist in Ordnung, dort zu sein, und das ist alles. Wenn Sie diese Zeile in Ihren.bashrc
Willen setzen, werden Sie viele Dinge kaputt machen./etc/init.d/cron
auf meinem System:value=`egrep "^${var}=" "$ENV_FILE" | tail -n1 | cut -d= -f2`
. Oder von/usr/bin/pdfjam
:pdftitl=`printf "%s" "$PDFinfo" | grep -e … | sed -e …`
. Ein Alias ist kein Problem, da er in Skripten nicht enthalten ist.GREP_OPTIONS
Vorhersagbarkeit von Pausen ist sehr schlecht, mit Ausnahme einiger Optionen--color=auto
(für die es entwickelt wurde).