xargs -I thay thế tùy chọn str


16

Theo hiểu biết của tôi, những điều sau đây có nghĩa chính xác như nhau:

ls -1 | xargs file {}
ls -1 | xargs -I{} file {}

nếu tùy chọn -I không được chỉ định, nó được mặc định là -I {}.

Tôi muốn liệt kê tất cả các tệp trong thư mục hiện tại và chạy filelệnh trên mỗi tệp. Một số có không gian trong tên của họ. Tuy nhiên, tôi nhận thấy sự khác biệt. Xem bên dưới:

$ ls -1
Hello World
$ ls -1 | xargs file {}
{}:    ERROR: cannot open `{}' (No such file or directory)
Hello: ERROR: cannot open `Hello' (No such file or directory)
World: ERROR: cannot open `World' (No such file or directory)
$ ls -1 | xargs -I{} file {}
Hello World: directory

Với -I {} được chỉ định rõ ràng, khoảng trắng trong tên tệp được xử lý như mong đợi.


3
"Nếu tùy chọn -I không được chỉ định, nó được mặc định là -I {}" - điều này không chính xác, ít nhất là với GNU xargs.
jjlin

Tôi hiểu sai lầm của mình. Tôi nên chỉ định xargs filehoặc xargs -I{} file {}. Không nên xargs file {}. Tôi đoán khi chỉ định rõ ràng -I {}, bash sẽ coi nó là file "Hello World". Không có -I {}, nó được coi là file Hello World.
tầm nhìn xa

1
(1) Thảo luận này ít liên quan đến shell (bash). (2) Thật tốt khi bạn biết -1tùy chọn này ls, nhưng nó được bật theo mặc định khi đầu ra của lsmột tệp hoặc một đường ống, vì vậy bạn không cần nó ở đây. (3) Bạn đang nhầm lẫn -Ivới tùy chọn không dùng nữa -i(chữ thường I). -ifoolà tương đương với -Ifoo, nhưng đồng bằng -ilà tương đương với -I{}. Nhưng sử dụng -I{}. (4) Nếu bạn thực sự muốn làm những gì bạn nói bạn muốn làm, tại sao không chỉ nói file *?
Scott

@Scott Mục đích ban đầu của tôi là viết `find. -name "* .mov" | xargs -I {} tệp {} `để tìm tất cả các tệp Mov theo cách đệ quy và chạy filetrên chúng. Nhưng tôi đã đưa ra một ví dụ đơn giản hơn bằng cách sử dụng ls. Bạn đúng rồi. Đối với điều đó, file *là tốt nhất.
tầm nhìn xa

1
tìm-exec.
Cristian Ciupitu

Câu trả lời:


20

Yêu -Icầu một giữ chỗ được xác định. Các -itùy chọn sẽ cho rằng {}là giữ chỗ. Đây là nơi tôi tìm thấy bất kỳ giả định nào về {} man xargsít nhất là trên Cygwin và CentOS.

xargs được gọi mà không có tùy chọn nào không cần giữ chỗ và nó chỉ nối STDIN vào cuối của các đối số.

Chỉ cần thêm echovào ví dụ của bạn để xem xargs đang làm gì:

$ ls -1
Hello World/

Ví dụ của bạn sử dụng nhầm {}:

$ ls -1 | xargs echo file {}
file {} Hello World/

vì vậy filecmd thấy args {} Hello Worldvà lỗi.

Nếu bạn muốn sử dụng một cách rõ ràng {}trong cuộc gọi xargs của mình:

$ ls -1 | xargs -i echo file {}
file Hello World/

Hoặc không có giữ chỗ:

$ ls -1 | xargs echo file
file Hello World/

xargs như đã gọi ở trên không cần {}. Nó nối STDIN vào cuối lệnh mà không có trình giữ chỗ. Việc sử dụng {} thường có nghĩa là bạn muốn STDIN ở đâu đó ở giữa cmd để thực thi, như trong:

$ ls -1 | xargs -i mv {} /path/to/someplace/.

Điều đó rất rõ ràng. Mặc dù câu trả lời của bạn hơi muộn, nhưng đọc nó thực sự củng cố sự hiểu biết của tôi.
foresightyj
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.