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.
find . -name '*.py' | xargs bash -c '. ~/.bashrc; grep -E regex_here "$@"' _
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.
find . -name '*.py' | xargs bash -c '. ~/.bashrc; grep -E "$0" "$@"' regex_here
Sie können die Alias-Suche explizit durchführen. Dann xargs
werde ich sehen grep -n --color=always
.
find . -name '*.py' | xargs "${BASH_ALIASES[grep]}" regex_here
In zsh:
find . -name '*.py' | xargs $aliases[grep] regex_here
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:
find . -name '*.py' -print0 | xargs -0 "${BASH_ALIASES[grep]}" regex_here
oder mit -exec
:
find . -name '*.py' -exec "${BASH_ALIASES[grep]}" regex_here {} +
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ühren shopt -s globstar
, um dieses Glob-Muster zu aktivieren.
grep regex_here **/*.py
Dies hat einige Einschränkungen:
- Wenn viele Dateien übereinstimmen (oder wenn sie lange Pfade haben), schlägt der Befehl möglicherweise fehl, weil er die maximale Befehlszeilenlänge überschreitet.
- In bash ≤4.2 (aber nicht in neueren Versionen, weder in ksh noch in zsh)
**/
werden symbolische Verknüpfungen zu Verzeichnissen erstellt.
Ein anderer Ansatz ist die Verwendung der Prozesssubstitution, wie von Marius Matutiae vorgeschlagen .
grep regex_here <(find . -name '*.py')
Dies ist nützlich, wenn dies **/
nicht zutrifft: für komplexe find
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 Setzen IFS
und Deaktivieren von Globbing , aber es wird langsam etwas komplexer:
(IFS=$'\n'; set -f; grep regex_here <(find . -name '*.py') )