Alias adalah internal ke shell di mana ia didefinisikan. Itu tidak terlihat oleh proses lain. Hal yang sama berlaku untuk fungsi shell. xargs
adalah aplikasi terpisah, yang bukan shell, jadi tidak memiliki konsep alias atau fungsi.
Anda dapat membuat xargs meminta shell alih-alih memohon grep
secara langsung. Namun, menjalankan shell saja tidak cukup, Anda harus mendefinisikan alias di shell itu juga. Jika alias didefinisikan di Anda .bashrc
, Anda dapat sumber file itu; namun ini mungkin tidak berfungsi saat Anda .bashrc
melakukan tugas lain yang tidak masuk akal di shell non-interaktif.
find . -name '*.py' | xargs bash -c '. ~/.bashrc; grep -E regex_here "$@"' _
Waspadalah terhadap seluk-beluk kutipan bersarang saat mengetik regexp. Anda dapat menyederhanakan hidup Anda dengan melewatkan regexp sebagai parameter ke shell.
find . -name '*.py' | xargs bash -c '. ~/.bashrc; grep -E "$0" "$@"' regex_here
Anda dapat melakukan pencarian alias secara eksplisit. Maka xargs
akan melihat grep -n --color=always
.
find . -name '*.py' | xargs "${BASH_ALIASES[grep]}" regex_here
Dalam zsh:
find . -name '*.py' | xargs $aliases[grep] regex_here
By the way, perhatikan bahwa find … | xargs …
pecah pada nama file yang mengandung spasi (antara lain) . Anda dapat memperbaikinya dengan mengubah catatan yang tidak dibatasi:
find . -name '*.py' -print0 | xargs -0 "${BASH_ALIASES[grep]}" regex_here
atau dengan menggunakan -exec
:
find . -name '*.py' -exec "${BASH_ALIASES[grep]}" regex_here {} +
Alih-alih menelepon find
, Anda dapat melakukan semuanya di dalam shell. Pola gumpal **/
melintasi direktori secara rekursif. Di bash, Anda harus menjalankan shopt -s globstar
untuk mengaktifkan pola gumpalan ini terlebih dahulu.
grep regex_here **/*.py
Ini memiliki beberapa keterbatasan:
- Jika banyak file cocok (atau jika memiliki jalur panjang), perintah tersebut mungkin gagal karena melebihi panjang baris perintah maksimum.
- Dalam bash ≤4.2 (tetapi tidak dalam versi yang lebih baru, atau di ksh atau zsh),
**/
berulang menjadi tautan simbolis ke direktori.
Pendekatan lain adalah dengan menggunakan substitusi proses, seperti yang disarankan oleh MariusMatutiae .
grep regex_here <(find . -name '*.py')
Ini berguna ketika **/
tidak berlaku: untuk find
ekspresi kompleks , atau dalam bash ≤4.2 ketika Anda tidak ingin berulang di bawah tautan simbolis. Perhatikan bahwa ini memecah nama file yang berisi spasi; solusinya adalah mengatur IFS
dan menonaktifkan globbing , tapi itu mulai menjadi sedikit rumit:
(IFS=$'\n'; set -f; grep regex_here <(find . -name '*.py') )