2012-04-04 32 views
5

Tôi đang cố gắng làm việc này một cách không thành công cho đến nay Tôi có một đầu ra lệnh mà tôi cần nhai để làm cho nó phù hợp để xử lý thêmTôi đang bối rối ở đây về awk, sed, v.v.

văn bản tôi có là:

1/2 [3] (27/03/2012 19:32:54) word word word word 4/5 

những gì tôi cần là để giải nén chỉ số 1/2 [3] 4/5 vì vậy nó sẽ xem xét:

1 2 3 4 5 

vì vậy, về cơ bản tôi đã cố gắng loại trừ tất cả các ký tự thứ tại không phải là chữ số, như "/", "[", "]", v.v. Tôi đã thử awk với FS, đã thử sử dụng regexp, nhưng không có cố gắng nào của tôi thành công.

Sau đó tôi sẽ thêm thứ gì đó vào nó như trước: 1 giây: 2 giây: 3 .... v.v. Hãy nhớ rằng tôi đang nói về một tệp có chứa rất nhiều dòng có cùng cấu trúc, nhưng tôi đã mặc dù về việc sử dụng awk để tổng hợp tất cả các cột với

awk '{sum1+=$1 ; sum2+=$2 ;......etc} END {print "first:"sum1 " second:"sum2.....etc}' 

nhưng trước tiên tôi sẽ cần phải giải nén chỉ số có liên quan, ngày mà là ở giữa "()" có thể được bỏ qua hoàn toàn nhưng họ là những con số do đó, việc lọc chỉ bằng các chữ số sẽ không đủ vì nó sẽ đối sánh với chúng quá

Hy vọng bạn có thể giúp tôi Cảm ơn bạn trước!

Trả lời

5

này: sed -r 's/[(][^)]*[)]/ /g; s/[^0-9]+/ /g' nên làm việc. Nó làm cho hai đường chuyền, loại bỏ các biểu thức được lồng vào trước và sau đó thay thế tất cả các chữ số không có các dấu cách đơn.

+0

TUYỆT VỜI! chính xác những gì tôi cần! Đây là cách toàn bộ lệnh trông giống như tệp test.txt chứa: '10/20 [30] (ngày) từ word word 40/50 10/20 [30] (ngày) từ word word 40/50 ' Vì vậy, khi chạy: ' cat test.txt | sed -r 's/[(] [^)] * [)]// g; s/[^ 0-9] +// g '| awk '{sum1 + = $ 1; sum2 + = $ 2; sum3 + = $ 3; sum4 + = $ 4; sum5 + = $ 5} END {print "đầu tiên:" sum1, "second:" sum2, "third:" sum3, "thứ tư:" sum4, "fifth:" sum5} '' và đầu ra: ' đầu tiên: 20 giây : 40 thứ ba: 60 thứ tư: 80 thứ năm: 100' Cảm ơn rất nhiều @ Michał Kosmulski Các bạn tuyệt vời – TuxSax

+0

BTW, có cách nào để làm cho nhận xét trông đẹp hơn như câu trả lời và câu hỏi không? Giống như các khối mã và thụt dòng, ngắt dòng, v.v. – TuxSax

+0

Bạn được chào đón. Đối với định dạng, hãy xem trang này: http://stackoverflow.com/editing-help#comment-formatting –

2

Bạn có thể làm điều gì đó như sed -e 's/(.*)//' -e 's/[^0-9]/ /g'. Nó xóa tất cả mọi thứ bên trong dấu ngoặc tròn, thay vì thay thế tất cả các ký tự không phải chữ số bằng dấu cách. Để thoát khỏi không gian thêm bạn có thể ăn nó để column -t:

$ echo '1/2 [3] (27/03/2012 19:32:54) word word word word 4/5' | sed -e 's/(.*)//' -e 's/[^0-9]/ /g' | column -t 
1 2 3 4 5 
+0

1UP Đây là những gì tôi đã nghĩ ra. – MattH

0

xem dưới đây, nếu nó là những gì bạn muốn:

kent$ echo "1/2 [3] (27/03/2012 19:32:54) word word word word 4/5"|sed -r 's/\([^)]*\)//g; s/[^0-9]/ /g' 
1 2 3      4 5 

nếu bạn muốn nó trông đẹp hơn:

kent$ echo "1/2 [3] (27/03/2012 19:32:54) word word word word 4/5"|sed -r 's/\([^)]*\)//g; s/[^0-9]/ /g;s/ */ /g' 
1 2 3 4 5 
0

Điều này sẽ cung cấp cho bạn các chữ số được trích xuất ngoài văn bản trong ngoặc đơn:

digits=$(echo '1/2 [3] (27/03/2012 19:32:54) word word word word 4/5' |\ 
     sed 's/(.*)//' | grep -o '[0-9][0-9]*') 
echo $digits 

hoặc tinh khiết giải pháp sed:

echo '1/2 [3] (27/03/2012 19:32:54) word word word word 4/5' |\ 
sed -e 's/(.*)//' -e 's/[^0-9]/ /g' -e 's/[ \t][ \t]*/ /g' 

OUTPUT:

1 2 3 4 5 
+0

tôi đã suy nghĩ về grep -o [0-9], tuy nhiên nó sẽ thất bại nếu số có hai chữ số, như 1/20 [35] ... – Kent

+0

Tôi đã chỉnh sửa câu trả lời của mình và thêm một tùy chọn khác dựa trên sed thuần túy. – anubhava

0
awk '{ first+=gensub("^([0-9]+)/.*","\\1","g",$0) 
     second+=gensub("^[0-9]+/([0-9]+) .*","\\1","g",$0) 
     thirdl+=gensub("^[0-9]+/[0-9]+ \[([0-9]+)\].*","\\1","g",$0) 
     fourth+=gensub("^.* ([0-9]+)/[0-9]+ *$","\\1","g",$0) 
     fifth+=gensub("^.* [0-9]+/([0-9]+) *$","\\1","g",$0) 
     } 
     END { print "first: " first " second: " second " third: " third " fourth: " fourth " fifth: " fifth 
     } 

Có thể phù hợp với bạn.

0

một đường chuyền với awk là đủ nếu bạn thiết lập một tách lĩnh vực ưa thích: bất kỳ một trong những dấu gạch chéo, không gian, khung mở hoặc khung gần tách một lĩnh vực:

awk -F '[][/ ]' ' 
    {s1+=$1; s2+=$2; s3+=$4; s4+=$(NF-1); s5+=$NF} 
    END {printf("first:%d second:%d third:%d fourth:%d fifth:%d\n", s1, s2, s3, s4, s5)} 
' 
1

TXR:

@(collect) 
@one/@two [@three] (@date @time) @(skip :greedy) @four/@five 
@(filter :tonumber one two three four five) 
@(end) 
@(bind (first second third fourth fifth) 
     @(mapcar (op apply +) (list one two three four five))) 
@(output) 
first:@first second:@second third:@third fourth:@fourth fifth:@fifth 
@(end) 

dữ liệu:

1/2 [3] (27/03/2012 19:32:54) word word word word 4/5 
10/20 [30] (27/03/2012 19:32:54) word word 40/50 

chạy:

$ txr data.txr data.txt 
first:11 second:22 third:33 fourth:44 fifth:55 

dễ dàng để thêm một số kiểm tra lỗi:

@(collect) 
@ (cases) 
@one/@two [@three] (@date @time) @(skip :greedy) @four/@five 
@ (or) 
@line 
@ (throw error `badly formatted line: @line`) 
@ (end) 
@ (filter :tonumber one two three four five) 
@(end) 
@(bind (first second third fourth fifth) 
     @(mapcar (op apply +) (list one two three four five))) 
@(output) 
first:@first second:@second third:@third fourth:@fourth fifth:@fifth 
@(end) 

$ txr data.txr - 
foo bar junk 
txr: unhandled exception of type error: 
txr: ("badly formatted line: foo bar junk") 
Aborted 

TXR là dành cho lập trình mạnh mẽ. Có cách đánh mạnh, vì vậy bạn không thể coi chuỗi là số vì chúng chứa chữ số. Các biến phải được ràng buộc trước khi sử dụng, và do đó các biến sai chính tả không âm thầm mặc định là 0 hoặc trống, mà đúng hơn là tạo ra lỗi loại unbound variable <name> in <file>:<line>. Việc trích xuất văn bản được thực hiện với nhiều ngữ cảnh cụ thể để bảo vệ chống lại việc nhập sai thông tin trong một định dạng như đang ở định dạng khác.

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