Một bí danh là nội bộ của vỏ nơi nó được xác định. Nó không thể nhìn thấy cho các quá trình khác. Các chức năng vỏ cũng vậy. xargs
là một ứng dụng riêng biệt, không phải là trình bao, do đó không có khái niệm bí danh hoặc hàm.
Bạn có thể thực hiện xargs gọi shell thay vì gọi grep
trực tiếp. Tuy nhiên, chỉ cần gọi một shell là không đủ, bạn cũng phải xác định bí danh trong shell đó. Nếu bí danh được xác định trong của bạn .bashrc
, bạn có thể nguồn tệp đó; tuy nhiên điều này có thể không hoạt động khi bạn .bashrc
thực hiện các nhiệm vụ khác không có ý nghĩa trong vỏ không tương tác.
find . -name '*.py' | xargs bash -c '. ~/.bashrc; grep -E regex_here "$@"' _
Cẩn thận với sự phức tạp của trích dẫn lồng nhau khi gõ regrec. Bạn có thể đơn giản hóa cuộc sống của mình bằng cách chuyển regrec làm tham số cho shell.
find . -name '*.py' | xargs bash -c '. ~/.bashrc; grep -E "$0" "$@"' regex_here
Bạn có thể thực hiện tra cứu bí danh một cách rõ ràng. Rồi xargs
sẽ thấy grep -n --color=always
.
find . -name '*.py' | xargs "${BASH_ALIASES[grep]}" regex_here
Trong zsh:
find . -name '*.py' | xargs $aliases[grep] regex_here
Nhân tiện, lưu ý rằng find … | xargs …
phá vỡ tên tập tin có chứa khoảng trắng (trong số những người khác) . Bạn có thể khắc phục điều này bằng cách thay đổi thành các bản ghi được phân tách bằng null:
find . -name '*.py' -print0 | xargs -0 "${BASH_ALIASES[grep]}" regex_here
hoặc bằng cách sử dụng -exec
:
find . -name '*.py' -exec "${BASH_ALIASES[grep]}" regex_here {} +
Thay vì gọi find
, bạn có thể làm mọi thứ hoàn toàn bên trong vỏ. Các mẫu toàn cầu **/
đi qua các thư mục đệ quy. Trong bash, bạn cần chạy shopt -s globstar
để kích hoạt mẫu hình cầu này trước.
grep regex_here **/*.py
Điều này có một vài hạn chế:
- Nếu nhiều tệp khớp với nhau (hoặc nếu chúng có đường dẫn dài), lệnh có thể thất bại vì vượt quá độ dài dòng lệnh tối đa.
- Trong bash .24.2 (nhưng không phải trong các phiên bản gần đây hơn, cũng không phải trong ksh hoặc zsh),
**/
đệ quy thành các liên kết tượng trưng đến các thư mục.
Một cách tiếp cận khác là sử dụng thay thế quá trình, theo đề xuất của MariusMatutiae .
grep regex_here <(find . -name '*.py')
Điều này hữu ích khi **/
không áp dụng được: đối với các find
biểu thức phức tạp hoặc trong bash .24.2 khi bạn không muốn lặp lại theo các liên kết tượng trưng. Lưu ý rằng điều này phá vỡ tên tập tin có chứa khoảng trắng; một cách giải quyết là thiết lập IFS
và vô hiệu hóa toàn cầu , nhưng nó bắt đầu hơi phức tạp:
(IFS=$'\n'; set -f; grep regex_here <(find . -name '*.py') )