Các lệnh đường ống sau một xargs đường ống


38

HP-UX ***** B.11.23 U ia64 **** giấy phép người dùng không giới hạn

find . -type d -name *log* | xargs ls -la

cung cấp cho tôi tên thư mục (tên chứa logtrong tên thư mục) theo sau là tất cả các tệp trong thư mục đó.

Các thư mục  /var/opt/SID/application_a/log/,  /var/opt/SID/application_b/log/,  /var/opt/SID/application_c/log/và vân vân chứa file log.

Tôi muốn chỉ có hai logfiles mới nhất được liệt kê bằng lslệnh, mà tôi thường tìm thấy bằng cách sử dụng ls -latr | tail -2.

Đầu ra phải là một cái gì đó như thế này ..

/var/opt/SID/application_a/log/
-rw-rw-rw-   1 user1    user1      59698 Jun 11  2013 log1
-rw-rw-rw-   1 user1    user1      59698 Jun 10  2013 log2
/var/opt/SID/application_b/log/
-rw-rw-rw-   1 user1    user1      59698 Jun 11  2013 log1
-rw-rw-rw-   1 user1    user1      59698 Jun 10  2013 log2
/var/opt/SID/application_c/log/
-rw-rw-rw-   1 user1    user1      59698 Jun 11  2013 log1
-rw-rw-rw-   1 user1    user1      59698 Jun 10  2013 log2

find . -type d -name *log* | xargs ls -la | tail -2không cho tôi kết quả trên. Những gì tôi nhận được là một danh sách hai tập tin find . -type d -name *log* | xargs ls -lalệnh cuối cùng .

Vì vậy, tôi có thể lệnh ống sau một đường ống xargs? Làm thế nào khác để tôi truy vấn, để có được danh sách các tập tin kết quả ở định dạng trên?

find . -type d -name *log* | xargs sh -c "ls -ltr | tail -10"

cung cấp cho tôi một danh sách mười tên thư mục bên trong thư mục hiện tại /var/opt/SIDvà đó không phải là điều tôi muốn.


2
Bạn nên trích dẫn *log*nếu không vỏ sẽ mở rộng nó.
Anthon

Xin lưu ý rằng sh -cmong đợi tên lệnh (tham số 0) là đối số thứ hai của nó, vì vậy bạn nên luôn luôn làm như vậy find . -type d -name *log* | xargs sh -c "ls -ltr | tail -10" lstail(chú ý lstailở cuối, sẽ phục vụ như $0đối với shell đã tạo). Nếu không, kết quả đầu tiên của bạn sẽ điền vào vai trò đó và không được sử dụng.
Jonas

Câu trả lời:


57

Bạn gần như ở đó. Trong lệnh cuối cùng của bạn, bạn có thể sử dụng -Iđể làm lschính xác

-I replace-str

    Thay thế các lần xuất hiện của str-str trong các đối số ban đầu bằng các tên được đọc từ đầu vào tiêu chuẩn. Ngoài ra, khoảng trống không trích dẫn không chấm dứt các mục đầu vào; thay vào đó dấu phân cách là ký tự dòng mới. Ngụ ý -x-L 1.

Vì vậy

find . -type d -name "*log*" | xargs -I {} sh -c "echo {}; ls -la {} | tail -2"

bạn sẽ echotìm thấy thư mục được tìm thấy bởi find, sau đó thực hiện ls | tailnó.


tìm thấy . -type d -name " log " | xargs -I {} sh -c "echo {}; ls -ltr {} | grep -E \" file_in | file tựa \ "| tail -5" Tôi đã sử dụng cái này.
khác1

3
Tôi làm vớixargs -n 1 sh -c 'echo $0'
Ginhing

1
trên macOS, sự thay thế không hoạt động trong lệnh được trích dẫn, vì vậy rất echo $0hữu ích (và dễ hiểu hơn)
mpuncel

1
Để làm cho nó làm việc với tên tập tin với không gian, sử dụng -print0, xargs -0và trốn thoát {}vào dấu ngoặc kép bên trong các shlệnh:find . -type d -name "*log*" -print0 | xargs -0 -I {} sh -c "echo \"{}\";ls -la \"{}\" | tail -2"
Benedikt Koppel

Tôi sử dụng tiếng vang "xargs -n 1 sh -c" \ $ 0 | $ func "` nếu tôi cần phải sử dụng biến $ func
thần


2

Chỉ ngoài fredtantini và như là một sự làm rõ chung (vì các tài liệu hơi khó hiểu):

Các xargs -I {}sẽ lấy '{}' nhân vật từ đầu vào tiêu chuẩn và thay thế chúng với bất cứ điều gì xuất phát từ các đường ống. Điều này có nghĩa là bạn thực sự có thể thay thế {}bằng bất kỳ kết hợp ký tự nào (có thể để phù hợp hơn với hương vị lập trình ưa thích của bạn). Ví dụ : xargs -I % sh -c "echo %". Nếu bạn luôn sử dụng, xargs -I {}bạn có thể thay thế nó xargs -ivì nó là tốc ký.

Các sh -csẽ cho bash của bạn / shell để đọc lệnh tiếp theo từ một chuỗi và không phải từ đầu vào tiêu chuẩn. Vì vậy, viết sh -c "echo something"là tương đương với echo something.

Các xargs -I {} sh -c "echo {}"sẽ đọc đầu vào mà bạn đã tạo với sh -cđó là echo {}. Vì bạn đã bảo nó thay thế {}bằng các đối số bạn nhận được từ đường ống, đó là điều sẽ xảy ra.

Bạn có thể dễ dàng kiểm tra điều này ngay cả khi không có đường ống, chỉ cần gõ lệnh trên trong một thiết bị đầu cuối. Bất cứ điều gì bạn viết tiếp theo sẽ được đưa ra thiết bị đầu cuối (Ctrl-D để thoát).

Trong ls -la {}lệnh điều tương tự lại xảy ra. Nó {}được thay thế bằng nội dung của lệnh pre-pipe.

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.