xargs đặc biệt hữu ích khi bạn có một danh sách các filepath trên stdin và muốn làm gì đó với chúng. Ví dụ:
$ git ls-files "*.tex" | xargs -n 1 sed -i "s/color/colour/g"
Hãy xem xét từng bước này:
$ git ls-files "*.tex"
tex/ch1/intro.tex
tex/ch1/motivation.tex
....
Nói cách khác, đầu vào của chúng tôi là một danh sách các đường dẫn mà chúng tôi muốn làm gì đó.
Để tìm hiểu những gì xargs làm với các đường dẫn này, một mẹo hay là thêm vào echo
trước lệnh của bạn, như vậy:
$ git ls-files "*.tex" | xargs -n 1 echo sed -i "s/color/colour/g"
sed -i "s/color/colour/g" tex/ch1/intro.tex
sed -i "s/color/colour/g" tex/ch1/motivation.tex
....
Đối -n 1
số sẽ làm cho xargs biến mỗi dòng thành một lệnh của riêng nó. Các sed -i "s/color/colour/g"
lệnh sẽ thay thế tất cả các lần xuất hiện của color
với colour
cho một file nào đó.
Lưu ý rằng điều này chỉ hoạt động nếu bạn không có bất kỳ khoảng trống nào trên đường dẫn của mình. Nếu bạn làm như vậy, bạn nên sử dụng các đường dẫn kết thúc null làm đầu vào cho xargs bằng cách chuyển -0
cờ. Một ví dụ sử dụng sẽ là:
$ git ls-files -z "*.tex" | xargs -0 -n 1 sed -i "s/color/colour/g"
Điều này không giống như những gì chúng tôi đã mô tả ở trên, nhưng cũng hoạt động nếu một trong các đường dẫn có một khoảng trống trong đó.
Điều này hoạt động với bất kỳ lệnh nào tạo ra tên tệp như đầu ra như find
hoặc locate
. Nếu bạn tình cờ sử dụng nó trong kho git với rất nhiều tệp, thì có thể hiệu quả hơn khi sử dụng nó git grep -l
thay vì git ls-files
, như vậy:
$ git grep -l "color" "*.tex" | xargs -n 1 sed -i "s/color/colour/g"
Các git grep -l "color" "*.tex"
lệnh sẽ đưa ra một danh sách các file "* .tex" chứa cụm từ "màu".
xargs
và$(...)
), xargs an toàn hơn nhiều so với thay thế lệnh. Và tôi không thể nhớ lại đã từng bắt gặp một tên tệp hợp pháp với một dòng mới trong đó. Không phải là các vấn đề cạm bẫy mở rộng và thoát từ với sự thay thế lệnh, không phải là xargs?