2013-09-11 37 views
11

Trong thư mục hiện tại, tôi muốn in tên tệp và nội dung trong đó. tôi có thể in tên tập tin hoặc nội dung riêng biệt bởixargs với nhiều lệnh

find . | grep "file_for_print" | xargs echo 
find . | grep "file_for_print" | xargs cat 

nhưng những gì tôi muốn là in chúng lại với nhau như thế này:

file1 
line1 inside file1 
line2 inside file1 
file2 
line1 inside file2 
line2 inside file2 

tôi đọc xargs with multiple commands as argument và cố gắng

find . | grep "file_for_print" | xargs -I % sh -c 'echo; cat;' 

nhưng doesn' t làm việc. Tôi không quen thuộc với xargs, vì vậy không biết chính xác "-I% sh -c" có nghĩa là gì. có ai giúp tôi không? cảm ơn bạn!

+0

thử này ..... tôi nghĩ rằng điều này sẽ giúp "tìm |. grep 'file_for_print' | xargs hơn" – nsd

Trả lời

14

Để bắt đầu, hầu như không có sự khác biệt giữa:

find . | grep "file_for_print" | xargs echo 

find . -name "file_for_print*" 

ngoại trừ điều thứ hai sẽ không phù hợp với tên tập tin như this_is_not_the_file_for_print, và nó sẽ in tên tập tin một cho mỗi hàng. Nó cũng sẽ nhanh hơn rất nhiều, bởi vì nó không cần phải tạo và in toàn bộ cấu trúc thư mục đệ quy chỉ để cho grep quăng hầu hết nó đi.

find . -name "file_for_print*" 

thực sự là chính xác giống như

find . -name "file_for_print*" -print 

nơi in -print hành động mỗi tên tập tin phù hợp tiếp theo là một dòng mới. Nếu bạn không cung cấp find với bất kỳ hành động nào, nó giả định bạn muốn -print. Nhưng nó có nhiều thủ thuật hơn tay áo của nó hơn thế. Ví dụ:

find . -name "file_for_print*" -exec cat {} \; 

Các -exec nguyên nhân hành động tìm đến thực hiện lệnh sau, lên đến \;, thay thế {} với mỗi tên tập tin phù hợp.

find không giới hạn trong một hành động. Bạn có thể yêu cầu nó làm nhiều thứ bạn muốn. Vì vậy:

find . -name "file_for_print*" -print -exec cat {} \; 

có thể sẽ làm khá tốt những gì bạn muốn.

Đối với các lô thêm thông tin về tiện ích này rất hữu ích, kiểu:

man find 

hoặc

info find 

và đọc tất cả về nó.

+5

1 cho có thể là giao một cách nhẹ nhàng nhất RTFM ;-) – necromancer

+0

vâng tìm và xargs là khá tuyệt vời. – sashang

16

find . | grep "file_for_print" | xargs -I % sh -c 'echo %; cat %;' (OP đã mất tích % s)

+1

Chính xác những gì tôi đang tìm kiếm! Cảm ơn bạn! – John

+0

vui mừng được trợ giúp :-) – necromancer

0

gì về cách viết chức năng bash của riêng bạn?

#!/bin/bash 

myFunction() { 
    while read -r file; do 
     echo "$file" 
     cat "$file" 
    done 
} 

find . -name "file_for_print*" | myFunction 
6

Vì chưa được nói: -I % yêu cầu xargs thay thế '%' bằng các đối số trong lệnh bạn cung cấp. Các sh -c '...' chỉ có nghĩa là chạy các lệnh '...' trong một vỏ mới.

Vì vậy

xargs -I % sh -c 'echo %; cat %;' 

sẽ chạy echo [filename] Tiếp theo cat [filename] cho mỗi tên tập tin cho xargs. Các lệnh echo và cat sẽ được thực hiện bên trong một quá trình shell khác nhưng điều này thường không quan trọng. Phiên bản của bạn không hoạt động vì thiếu các dấu hiệu % bên trong lệnh được chuyển đến xargs.


Đối với những gì nó có giá trị Tôi sẽ sử dụng lệnh này để đạt được điều tương:

find -name "*file_for_print*" | parallel 'echo {}; cat {};' 

vì nó đơn giản (parallel tự động sử dụng {} như nhân vật thay thế và có thể mất nhiều lệnh theo mặc định).

0

Trong trường hợp cụ thể này, mỗi lệnh được thực thi cho từng tệp riêng lẻ, vì vậy không có lợi thế khi sử dụng xargs. Bạn chỉ có thể thêm exec hai lần để bạn 'tìm':

find . -name "*file_for_print*" -exec echo {} \; -exec cat {} \; 

Trong trường hợp này -print có thể được sử dụng thay cho echo đầu tiên như đã chỉ ra bởi rici, nhưng ví dụ này cho thấy khả năng để thực hiện hai lệnh tùy ý với một đơn find

Các vấn đề liên quan