Học bằng cách đọc theo thứ tự

xargs — Xây dựng lệnh từ đầu vào chuẩn

Trải đầu vào chuẩn thành tham số với echo a b | xargs echo, chạy từng từ một với -n1, chèn giá trị vào {} bằng -I{}, và xử lý hàng loạt find . -name '*.log' | xargs — kèm sơ đồ và terminal trực tiếp.

Biến đầu vào chuẩn thành tham số — xargs và -n1

Pipe truyền đầu ra của lệnh trước thành đầu vào chuẩn của lệnh sau. Nhưng rmecho không đọc đầu vào chuẩn — chúng chỉ xử lý các giá trị được viết làm tham số. xargs là lệnh nhận những gì có trên đầu vào chuẩn và sắp xếp lại thành tham số cho lệnh bạn viết phía sau nó, nên với echo a b | xargs echo, ab trở thành tham số của echo ở cuối.

Mặc định, xargs truyền các từ nhận được tới một lần chạy duy nhất, gom lại càng nhiều càng tốt. Thêm -n1 thì nó tách chúng ra, chạy lệnh một lần cho mỗi từ.

Cú phápTác dụng
| xargsTrải đầu vào thành tham số và chạy lệnh
xargs -n1Chạy lệnh một lần cho mỗi tham số
xargs -I{}Thay {} bằng đầu vào và chèn vào bất kỳ đâu
find ... | xargsChạy một lần xử lý gom chung cho những gì tìm thấy
| xargs echo rmIn ra lệnh sẽ chạy để kiểm tra trước
xargs sắp xếp lại đầu vào thành tham số
echo a b cđầu vào chuẩna b c| xargs echo| xargs -n1 echoecho a b cgom, 1 lần chạyecho a / b / cmỗi từ 1, 3 lầnđầu rađưa qua pipeđưa qua pipechạy 1 lầnchạy mỗi từ
Đầu ra của echo được đưa qua pipe tới xargs làm đầu vào chuẩn và sắp xếp lại thành tham số. Một lần chạy gom chung, hay ba lần chạy từng từ một — đó là khác biệt mà -n1 tạo ra.
printf 'one two three\n' | xargs echo got:        # got: one two three (gom, 1 lần chạy)
printf 'one\ntwo\nthree\n' | xargs -n1 echo item:  # item: one / item: two / item: three

① Tạo tệp nguồn 3 dòng bằng printf 'red\ngreen\nblue\n' > colors.txt.

② Đưa đầu ra của cat colors.txt qua pipe vào xargs, trải các từ thành tham số cho echo để in tất cả trong một lần chạy gom chung.

③ Truyền cùng đầu vào đó cho xargs với tùy chọn tách từng từ một, và xác nhận rằng echo chạy ba lần, mỗi dòng một lần. (Khi bạn chạy đúng, phần giải thích sẽ hiện ra.)

Linux console
0 / 3 đã hoàn thành
Loading Linux Terminal...

Chuỗi thay thế và tích hợp find — -I{}

xargs -I{} xây dựng lệnh bằng cách chèn mỗi dòng đầu vào vào vị trí của `{}`. Vì {} có thể đặt ở bất kỳ đâu bạn muốn, kể cả giữa lệnh, bạn có thể chạy dạng như echo file_{}.txt — với văn bản cố định quanh giá trị — từng dòng một.

Khi bạn muốn chạy thứ gì đó trên các tệp mà find tìm ra, dạng find ... | xargs là chuẩn mực. xargs trải các đường dẫn mà find in ra thành tham số và chạy một lần xử lý gom chung trên kết quả tìm kiếm. Kết hợp với -I{} thì bạn có thể xử lý từng đường dẫn tìm thấy bằng cách chèn chúng từng cái một vào `{}`.

Xử lý những gì find tìm ra bằng xargs
find . -name '*.log'a.logb.log| xargs -I{} echo {}chèn mỗi dòngvào {}echo a.logecho b.login đường dẫnđưa qua pipechạy dòng 1chạy dòng 2
Các đường dẫn find in ra được truyền cho xargs theo 1 dòng = 1 mục, và -I{} chèn mỗi cái vào `{}` rồi chạy từng cái một.
printf 'alpha\nbeta\n' | xargs -I{} echo 'name = {}'   # name = alpha / name = beta
mkdir -p logs                                          # tạo thư mục nguồn
touch logs/a.log logs/b.log                             # tạo 2 tệp
find logs -name '*.log' | xargs -I{} echo 'found {}'    # found logs/a.log / found logs/b.log

① Thêm tùy chọn chuỗi thay thế vào printf 'cat\ndog\n' | xargs và in mỗi đầu vào được chèn vào {} trong pet = {}.

② Tạo thư mục bằng mkdir -p data, rồi tạo hai tệp bằng touch data/x.txt data/y.txt.

③ Đưa đầu ra của find data -name '*.txt' qua pipe vào xargs và dùng chuỗi thay thế để chèn mỗi đường dẫn vào {} trong echo 'hit {}'.

④ Cũng chạy find data -name '*.txt' | xargs echo thuần và so sánh với dạng mà, khi không có -I{}, các đường dẫn xếp hàng ở cuối.

Linux console
0 / 5 đã hoàn thành
Loading Linux Terminal...

Xử lý từng cái một — Chọn giữa -n1 và -I{}

Cả -n1 lẫn -I{} đều chạy lệnh từng mục một, nhưng chúng khác nhau ở vị trí giá trị đi vàocách đầu vào được tách. -n1 truyền các từ (các đoạn cách nhau bởi dấu cách hoặc dòng mới) từng cái một làm tham số ở cuối lệnh. -I{} lấy các dòng từng cái một và chèn chúng vào vị trí bạn viết `{}`.

Dùng `-n1` khi bạn chỉ cần giá trị ở cuối, và `-I{}` khi bạn muốn văn bản cố định quanh giá trị, như {}.bak.

Khía cạnh`-n1``-I{}`
Vị trí giá trị đi vàoXếp ở cuối lệnhVào nơi bạn viết {}
Đơn vị táchTừ (tách theo dấu cách/dòng mới)Dòng (1 dòng = 1 mục)
Phù hợp choChỉ truyền tham số lần lượtTạo dạng có văn bản cố định quanh giá trị
printf 'a\nb\n' | xargs -n1 echo prefix       # prefix a / prefix b (ở cuối)
printf 'a\nb\n' | xargs -I{} echo {}_done      # a_done / b_done (chèn giữa lệnh)

① Thêm tùy chọn chạy từng từ một vào printf 'log1\nlog2\n' | xargs, truyền chúng lần lượt làm tham số cho echo file.

② Truyền cùng đầu vào đó cho xargs và dùng tùy chọn chuỗi thay thế để chèn chúng vào {} trong echo {}.bak.

③ So sánh đầu ra thay đổi thế nào giữa việc xếp ở cuối và việc được chèn giữa lệnh.

Linux console
0 / 2 đã hoàn thành
Loading Linux Terminal...

Xử lý hàng loạt trong thực tế — Kiểm tra trước khi chạy

Trong công việc thực tế, bạn dùng xargs để sao chép hàng loạt và xóa hàng loạt trên các đối tượng mà find thu thập. Vì -I{} có thể chèn cùng một giá trị vào hai vị trí trở lên, nó hoạt động với các lệnh nhận hai tham số như cp nguồn đích, cho phép bạn tạo bản sao lưu "tên gốc + .bak" cùng một lúc.

Đừng chạy ngay các thao tác không thể hoàn tác như rm. Nếu bạn chạy xargs echo rm trước xargs rm, lệnh sẽ chạy chỉ được in ra và không có gì bị xóa. Hãy kiểm tra các đối tượng được liệt kê, rồi bỏ echo và chạy thật — cách hai bước kiểm-tra-rồi-chạy này là cách an toàn.

Kiểm tra xóa hàng loạt bằng cách in trước khi chạy
find . -name '*.tmp'a.tmpb.tmp| xargs echo rm| xargs rmrm a.tmp b.tmpchỉ in raxóa cả haitệp cùng lúcin đối tượng① kiểm tra trước② khi đã chắckhông xóa gìchạy thật
Với các thao tác không thể hoàn tác, hãy chèn một echo trước rm để kiểm tra đối tượng bằng cách in ra trước, rồi chạy.
mkdir -p cache
touch cache/a.tmp cache/b.tmp
find cache -name '*.tmp' | xargs echo rm   # chỉ in ra rm cache/a.tmp cache/b.tmp
find cache -name '*.tmp' | xargs rm        # chạy thật khi đã chắc

① Tạo thư mục làm việc bằng mkdir -p work, rồi tạo hai tệp nguồn bằng touch work/note1.txt work/note2.txt.

② Đưa đầu ra của find work -name '*.txt' qua pipe vào xargs và dùng chuỗi thay thế để sao chép mỗi tệp thành "tên gốc với .bak thêm vào cuối."

③ Xác nhận bằng ls work rằng đã có thêm hai tệp .bak.

④ Truyền đầu ra của find work -name '*.bak' cho xargs, chèn một echo trước lệnh xóa, và kiểm tra lệnh xóa sẽ chạy bằng cách chỉ in ra.

⑤ Nếu các đối tượng được liệt kê trông ổn, hãy bỏ echo, xóa các tệp .bak cùng một lúc, và xác nhận lại bằng ls work rằng chúng đã biến mất.

Linux console
0 / 6 đã hoàn thành
Loading Linux Terminal...
QUIZ

Kiểm tra kiến thức

Hãy trả lời từng câu hỏi một.

Câu 1Đâu là mô tả đúng về việc xargs làm?

Câu 2printf 'a\nb\nc\n' | xargs -n1 echo hoạt động thế nào?

Câu 3{} đại diện cho gì trong xargs -I{}?