2013-05-31 13 views
5

Nói rằng tôi có một tập tin như vậy:Bất kỳ cách nào để tìm xem hai dòng liền kề mới có bắt đầu bằng các từ nhất định không?

+jaklfjdskalfjkdsaj 
fkldsjafkljdkaljfsd 
-jslakflkdsalfkdls; 
+sdjafkdjsakfjdskal 

Tôi chỉ muốn tìm và đếm số lần trong tập tin này một dòng bắt đầu với - được ngay lập tức theo sau là một dòng bắt đầu với +.

Rules:

  • Không kịch bản bên ngoài
  • Phải được thực hiện từ bên trong một kịch bản bash
  • Phải inline

tôi có thể tìm ra cách để làm điều này trong một kịch bản Python , ví dụ, nhưng tôi chưa bao giờ phải làm điều gì đó rộng rãi trong Bash.

Có ai có thể giúp tôi không? Tôi hình dung nó sẽ kết thúc là grep, perl, hoặc có thể là dòng sed tài năng - nhưng đây là những thứ tôi vẫn đang học.

Cảm ơn tất cả!

+2

loại bỏ các thẻ Python như bạn dường như không muốn một câu trả lời bằng cách sử dụng nó. –

+0

Cảm ơn! Tôi đã nói với tôi có thể sử dụng 'python', miễn là nó là nội tuyến, vì vậy tôi figured tôi muốn bao gồm nó anyway. Cảm ơn bạn đã sửa lỗi! –

+0

Python không tốt cho một lớp lót trên dòng lệnh ... do đó sẽ không phải là câu trả lời khả thi –

Trả lời

6

dễ dàng trong Perl:

perl -lne '$c++ if $p and /^\+/; $p = /^-/ }{ print $c' FILE 
+0

Điều này thật hoàn hảo! Bạn có phiền nếu tôi hỏi làm thế nào bạn đã bắt đầu học Perl regexes? Tôi dường như không thể bắt đầu quấn quanh đầu mình. –

+0

'} {' phải giống với 'END {}'. Có bất kỳ tham chiếu nào cho cú pháp này không? –

+1

@mpapec: Nó được gọi là "nhà điều hành chúc mừng Eskimo". Xem http://www.catonmat.net/blog/secret-perl-operators/#eskimo – choroba

1

awk một liner:

awk -v FS='' '{x=x sprintf("%s", $1)}END{print gsub(/-\+/,"",x)}' file 

ví dụ

kent$ cat file 
+jaklfjdskalfjkdsaj 
fkldsjafkljdkaljfsd 
-jslakflkdsalfkdls; 
+sdjafkdjsakfjdskal 
- 
- 
- 
+ 
- 
+ 
foo 
+ 

kent$ awk -v FS='' '{x=x sprintf("%s", $1)}END{print gsub(/-\+/,"",x)}' file 
3 
8

grep -A1 "^-" $file | grep "^+" | wc -l

Các grep đầu tiên tìm thấy tất cả các dòng bắt đầu bằng -, và -A1 làm cho nó cũng ra đường sau trận đấu quá.

Chúng tôi sau đó grep kết quả đầu ra cho bất kỳ dòng nào bắt đầu bằng +. Logic:

  1. Chúng ta biết đầu ra của grep đầu tiên chỉ là -XXX dòng và các dòng sau
  2. Chúng ta biết rằng một dòng +xxx cũng không thể là một dòng -xxx

Do đó, bất kỳ +xxx các dòng phải là các dòng sau và phải được tính, chúng tôi thực hiện với wc -l

1

Ví dụ khác về Perl.Không phải là ngắn gọn như của choroba, nhưng minh bạch hơn trong cách hoạt động:

perl -e'while (<>) { $last = $cur; $cur = $_; print $last, $cur if substr($last, 0, 1) eq "-" && substr($cur, 0, 1) eq "+" }' < infile 

Output:

-jslakflkdsalfkdls; 
+sdjafkdjsakfjdskal 
1

bash tinh khiết:

unset c p 
while read line ; do 
    [[ $line == +* && $p == 0 ]] && ((c++)) 
    [[ $line == -* ]] 
    p=$? 
done < FILE 
echo $c