39 Stimmen

Wie kann ich mit xargs Befehle verwenden?

Ich habe den folgenden Alias in meiner .aliases-Datei:

alias gi grep -i

und ich möchte nach foo in allen Dateien suchen, die den String bar im Namen haben, ohne auf die Groß- und Kleinschreibung zu achten:

find -name \*bar\* | xargs gi foo

Das ist was ich bekomme:

xargs: gi: Datei oder Verzeichnis nicht gefunden

Gibt es einen Weg, um Aliase in xargs zu nutzen, oder muss ich die Vollversion verwenden:

   find -name \*bar\* | xargs grep -i foo

Hinweis: Dies ist ein einfaches Beispiel. Neben gi habe ich einige ziemlich komplizierte Aliase, die ich nicht so einfach manuell erweitern kann.

Edit: Ich benutze tcsh, also bitte geben Sie an, ob eine Antwort shell-spezifisch ist.

35voto

camh Punkte 38167

Aliase sind shell-spezifisch - in diesem Fall wahrscheinlich bash-spezifisch. Um ein Alias auszuführen, müssen Sie bash ausführen, aber Aliase werden nur für interaktive Shells geladen (genauer gesagt, .bashrc wird nur für eine interaktive Shell gelesen).

bash -i startet eine interaktive Shell (und lädt .bashrc). bash -c cmd führt cmd aus.

Kombinieren Sie sie: bash -ic cmd führt cmd in einer interaktiven Shell aus, wobei cmd eine bash Funktion/Alias ist, die in Ihrer .bashrc definiert ist.

find -name \*bar\* | xargs bash -ic gi foo

sollte das tun, was Sie wollen.

Bearbeitung: Ich sehe, dass Sie die Frage mit "tcsh" getaggt haben, daher ist die bash-spezifische Lösung nicht anwendbar. Mit tcsh benötigen Sie nicht das -i, da es anscheinend .tcshrc liest, es sei denn, Sie geben -f.

Versuchen Sie dies:

find -name \*bar\* | xargs tcsh -c gi foo

Es hat in meinem Basis-Test funktioniert.

13voto

ken hicks Punkte 121

Diese Lösung hat perfekt für mich in bash funktioniert:
https://unix.stackexchange.com/a/244516/365245

Problem

[~]: alias grep='grep -i'
[~]: find -maxdepth 1 -name ".bashrc" | xargs grep name      # grep alias nicht erweitert
[~]: ### keine Übereinstimmungen gefunden ###

Lösung

[~]: alias xargs='xargs ' # Erstellen Sie ein xargs-Alias mit Leerzeichen am Ende
[~]: find -maxdepth 1 -name ".bashrc" | xargs grep name     # grep Alias wird erweitert
# Name     : .bashrc

Warum es funktioniert

[~]: man alias  
alias: alias [-p] [name[=value] ... ]  
(snip)  
Ein Leerzeichen am Ende von VALUE führt dazu, dass das nächste Wort auf Alias-Substitution überprüft wird, wenn das Alias erweitert wird.

8voto

Peter Ericson Punkte 1789

Ändern Sie "gi" stattdessen in ein Skript um

z.B. in /home/$USER/bin/gi:

#!/bin/sh
exec /bin/grep -i "$@"

Vergessen Sie nicht, die Datei als ausführbar zu markieren.

7voto

Pete TerMaat Punkte 3135

Der Vorschlag hier besteht darin, xargs zu vermeiden und stattdessen eine "while read"-Schleife anstelle von xargs zu verwenden:

find -name \*bar\* | while read file; do gi foo "$file"; done

Sehen Sie die akzeptierte Antwort im obigen Link für Verbesserungen, um mit Leerzeichen oder Zeilenumbrüchen in Dateinamen umzugehen.

2voto

Tom Hale Punkte 32065

Dies ist sicher bei Sonderzeichen:

find . -print0 | xargs -0 bash -ic 'gi foo "$@"' --

Die Optionen -print0 und -0 verwenden \0 oder NUL-terminierte Zeichenketten, damit keine seltsamen Dinge passieren, wenn Dateinamen Leerzeichen enthalten.

bash setzt das erste Argument nach dem Befehlsstring als $0, daher übergeben wir ein Dummy-Argument (--), damit die erste Datei, die von find aufgelistet wird, nicht von $0 konsumiert wird.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X