Un alias è interno alla shell in cui è definito. Non è visibile ad altri processi. Lo stesso vale per le funzioni della shell. xargs
è un'applicazione separata, che non è una shell, quindi non ha un concetto di alias o funzioni.
Puoi fare in modo che xargs invochi una shell invece di invocare grep
direttamente. Tuttavia, solo invocare una shell non è sufficiente, è necessario definire anche l'alias in quella shell. Se l'alias è definito nel tuo .bashrc
, puoi sorgente quel file; tuttavia, ciò potrebbe non funzionare se si .bashrc
eseguono altre attività che non hanno senso in una shell non interattiva.
find . -name '*.py' | xargs bash -c '. ~/.bashrc; grep -E regex_here "$@"' _
Fai attenzione alle complessità delle quotazioni nidificate quando digiti regexp. Puoi semplificare la tua vita passando regexp come parametro alla shell.
find . -name '*.py' | xargs bash -c '. ~/.bashrc; grep -E "$0" "$@"' regex_here
È possibile eseguire la ricerca alias in modo esplicito. Quindi xargs
vedrà grep -n --color=always
.
find . -name '*.py' | xargs "${BASH_ALIASES[grep]}" regex_here
In zsh:
find . -name '*.py' | xargs $aliases[grep] regex_here
A proposito, nota che si find … | xargs …
rompe su nomi di file contenenti spazi (tra gli altri) . È possibile risolvere questo problema passando a record delimitati da null:
find . -name '*.py' -print0 | xargs -0 "${BASH_ALIASES[grep]}" regex_here
o usando -exec
:
find . -name '*.py' -exec "${BASH_ALIASES[grep]}" regex_here {} +
Invece di chiamare find
, puoi fare tutto interamente all'interno della shell. Il modello glob **/
attraversa ricorsivamente le directory. In bash, devi eseguire shopt -s globstar
per abilitare prima questo schema glob.
grep regex_here **/*.py
Questo ha alcune limitazioni:
- Se molti file corrispondono (o se hanno percorsi lunghi), il comando potrebbe non riuscire perché supera la lunghezza massima della riga di comando.
- In bash ≤4.2 (ma non nelle versioni più recenti, né in ksh o zsh),
**/
ricorre in collegamenti simbolici alle directory.
Un altro approccio consiste nell'utilizzare la sostituzione del processo, come suggerito da MariusMatutiae .
grep regex_here <(find . -name '*.py')
Ciò è utile quando **/
non è applicabile: per find
espressioni complesse o in bash ≤4.2 quando non si desidera ricorrere sotto collegamenti simbolici. Si noti che ciò si interrompe sui nomi dei file contenenti spazi; una soluzione è quella di serie IFS
e globbing disabilitare , ma sta cominciando a diventare un po 'complessa:
(IFS=$'\n'; set -f; grep regex_here <(find . -name '*.py') )