2014-06-05 20 views
6

Tôi đã cố gắng làm cho tập lệnh tôi viết đơn giản và đơn giản hơn.Dễ dàng đếm các từ trong danh sách tệp trong thư mục sau lệnh grep -v

Có nhiều cách để viết lấy số lượng từ của tất cả các tệp trong một thư mục hoặc thậm chí tất cả các tệp của thư mục con của một thư mục.

Ví dụ, tôi có thể viết

wc */* 

và tôi có thể nhận được kết quả như thế này (đây là đầu ra mong muốn):

0  0  0 10.53400000/YRI.GS000018623.NONSENSE.vcf 
    0  0  0 10.53400000/YRI.GS000018623.NONSTOP.vcf 
    0  0  0 10.53400000/YRI.GS000018623.PFAM.vcf 
    0  0  0 10.53400000/YRI.GS000018623.SPAN.vcf 
    0  0  0 10.53400000/YRI.GS000018623.SVLEN.vcf 
    2  20  624 10.53400000/YRI.GS000018623.SVTYPE.vcf 
    2  20  676 10.53400000/YRI.GS000018623.SYNONYMOUS.vcf 
    13  130  4435 10.53400000/YRI.GS000018623.TSS-UPSTREAM.vcf 
425  4250 126381 10.53400000/YRI.GS000018623.UNKNOWN-INC.vcf 

nhưng nếu có quá nhiều file, tôi có thể nhận được một thông báo lỗi như sau:

-bash: /usr/bin/wc: Argument list too long 

vì vậy, tôi có thể tạo biến và làm một thư mục tại một thời điểm, như vậy:

while read $FOLDER 
do 
    wc $FOLDER/* >> outfile.txt 
done < "$FOLDER_LIST" 

để điều này chuyển từ một dòng thành 5 giống như vậy.

Hơn nữa, trong một trường hợp, tôi muốn sử dụng grep -v đầu tiên, sau đó carryout đếm từ, như vậy:

grep -v dbsnp */* | wc 

nhưng điều này sẽ bị hai lỗi:

  1. Đối số danh sách quá dài
  2. Nếu nó không quá dài, nó sẽ cung cấp cho wc cho tất cả các tệp cùng một lúc, không phải cho mỗi tệp.

Vì vậy, để tóm tắt lại, tôi rất thích để có thể làm điều này:

grep -v dbsnp */* wc > Outfile.txt 
awk '{print $4,$1} Outfile.txt > Outfile.summary.txt 

và có nó trở đầu ra như tôi đã giới thiệu ở trên.

Có cách nào đơn giản để thực hiện việc này không? Hoặc tôi đang xem xét một vòng ở mức tối thiểu? Một lần nữa, tôi biết 101 cách để làm điều này giống như phần còn lại của chúng tôi bằng cách sử dụng một kịch bản dòng 4-10, nhưng tôi rất thích có thể chỉ cần gõ 2 một dòng vào dấu nhắc lệnh ... và kiến ​​thức về vỏ của tôi là chưa đủ sâu để biết những cách nào sẽ cho phép những gì tôi đang yêu cầu của hệ điều hành.

EDIT -

Một giải pháp đã được đề xuất:

find -exec grep -v dbsnp {} \; | xargs -n 1 wc 

Giải pháp này dẫn đến kết quả như sau:

wc: 1|0:53458644:AMBIGUOUS:CCAGGGC|-16&GCCAGGGCCAGGGC|-18&GCCAGGGCC|-19&GGCCAGGGC|-19&GCCAGGGCG|-19,.:48:48,48:4,4:0,17:-48,0,-48:0,0,-17:27:3,24:24: No such file or directory 
wc: 10: No such file or directory 
wc: 53460829: No such file or directory 
wc: .: Is a directory 
     0  0  0 . 
wc: AA: No such file or directory 
wc: CT: No such file or directory 
wc: .: Is a directory 
     0  0  0 . 
wc: .: Is a directory 
     0  0  0 . 

Như gần như tôi có thể nói, dường như được điều trị mỗi dòng dưới dạng tệp. Tôi vẫn đang xem xét các câu trả lời khác và cảm ơn sự giúp đỡ của bạn.

Trả lời

3

Bạn nói rằng "điều này không giải quyết vấn đề trả lại wc trong một mục-by-item thời trang"

Tiếp theo di chúc:

find -exec wc {} \; 

Nhưng điều này sẽ không đi kèm với grep của bạn lọc "grep -v"

Nếu bạn có ý định làm như vậy như được chỉ ra bởi nhận xét của tôi về câu trả lời này, sau đó xin vui lòng kiểm tra xem các công trình sau cho bạn:

find -exec bash -c "echo -n {}; grep -v dbsnp {} | wc " \; 
+0

@Vincent Tôi không thể hiểu được mục đích sử dụng 'grep -v', Nếu bạn có thể giải thích một chút về điều đó, có thể chúng ta sẽ thử và xây dựng một giải pháp xung quanh nó. ', và đếm các từ, hoặc bạn chỉ muốn loại trừ dbsnp khỏi số đếm từ? – PradyJord

+0

Tôi muốn loại trừ toàn bộ dòng, và Tôi nên thêm Tôi đang thực sự nhằm sử dụng wc -l Điều này làm việc và có hiệu quả dự định (tất cả các câu trả lời khác thực sự đã thất bại - cảm ơn bạn !!!) –

+0

xin vui lòng kiểm tra tìm 2 – PradyJord

2

Bạn có quá nhiều kết quả phù hợp với */* để grep nhận được danh sách đối số dài.Bạn có thể sử dụng find để phá vỡ này:

find -exec grep -v dbsnp {} \; | wc 

và có lẽ bạn muốn để thoát khỏi lỗi traversal tốt quá:

find -exec grep -v dbsnp {} \; 2> /dev/null | wc 
+0

Điều này rất thú vị. Tại sao lỗi wc, nhưng tìm thấy không? Làm thế nào tôi có thể đi về việc học những thứ như thế này, mà bạn dường như biết, nhưng tôi không? Tôi không thấy thông tin này trên trang người đàn ông cho wc. Ngoài ra, điều này không giải quyết được vấn đề trả lại wc theo kiểu thời trang từng mục; thay vào đó nó chỉ trả về tổng số. –

+0

@VincentLaufer Bạn sẽ muốn đọc về 'ARG_MAX' [ở đây] (http://www.in-ulm.de/~mascheck/various/argmax/). 'find -exec' được thiết kế để giải quyết vấn đề này bằng cách tập hợp thành các tập hợp phù hợp với' ARG_MAX' (xem [ở đây] (http://pubs.opengroup.org/onlinepubs/9699919799/utilities/find.html): * " Kích thước của bất kỳ tập hợp nào của hai hoặc nhiều tên đường dẫn sẽ bị giới hạn sao cho việc thực thi tiện ích không làm cho giới hạn {ARG_MAX} vượt quá giới hạn của hệ thống. "*. –

0

Dựa trên câu trả lời của perreal:

Nếu bạn muốn tập tin wc bởi tập tin, bạn có thể sử dụng xargs:

find -exec grep -v dbsnp {} \; | xargs -n 1 wc 

xargs có thể đọc các đầu vào tiêu chuẩn và xây dựng và thực hiện các dòng lệnh với nó. Vì vậy, nó đọc kết quả của dòng đầu vào của bạn và thực hiện wc cho mỗi mục duy nhất (-n 1).

+2

Ví dụ thứ hai của bạn cũng giống như nhiều 'ARG_MAX' như OP 'wc */*' là như vậy nó sẽ không hoạt động hoặc nếu việc mở rộng glob là quá lớn –

+0

Bạn đang phải Ok, anh ta nên đi với 'find' sau đó ... –

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