2013-01-04 32 views
6

Tôi có một tập hợp các dữ liệu mà trông như thế nàytìm kiếm nhiều lạnh chuỗi với awk

col1 col2 col3 col4 
ABC1 DEF1 GHI1 cond1 
ABC2 DEF2 GHI2 cond1-cond2 
ABC3 DEF3 GHI3 cond2/cond1 
ABC4 DEF4 GHI4 cond2 cond1 
ABC5 DEF5 GHI5 cond4/cond1 
ABC6 DEF6 GHI6 cond1 
ABC7 DEF7 GHI7 mcond1 
ABC8 DEF8 GHI8 cond2 
ABC9 DEF9 GHI9 cond1 at 50 
ABCa DEFa GHIa con cond1 
ABCb DEFb GHIb no. cond1 
ABCc DEFc GHIc cond1 something 
ABCc DEFc GHIc Mcond1 

Tôi cố gắng để viết một vài lệnh để tách dữ liệu theo "col4" để có được:

  1. Tệp có chứa chuỗi "cond1" với BẤT KTH NÀO trước hoặc sau TRỪ cho chữ "M" và "m". Tôi hiện đang sử dụng lệnh này (mà không loại trừ M và m, rõ ràng) cho việc này:

    awk 'BEGIN{IGNORECASE=1} $4 ~ /.cond1/ || $4 ~ /cond1./ ' /filepath.tab 
    

    xin vui lòng cũng không phải là lần thứ 4, 9 và các hàng thứ 11 của dữ liệu chứa dấu cách giữa "cond1" và khác chuỗi, tôi muốn điều này BAO GỒM trong tệp. (Liên kết "" trong lệnh bao gồm không gian?)

  2. Tôi đã viết một lệnh để có được một tập tin có chứa 'cond1' CHỈ trong 'col4'

    awk 'BEGIN{IGNORECASE=1} $4 ~ /^cond1$/ ' /filepath.tab 
    

    nó đang làm việc tốt với hầu hết các của dữ liệu, mặc dù tôi đang nhận được những 2 lỗi trong các kết quả:

    ABC9 DEF9 GHI9 cond1 at 50 
    ABCc DEFc GHIc cond1 something 
    

bất cứ ai có thể vui lòng giúp tôi với những 2 lệnh? Cảm ơn.

Tôi đang tìm kiếm một sản phẩm của 3 file mà không chứa bất kỳ bản sao, sau đây là một ví dụ: File1 (chứa tất cả các kết hợp với cond1):

col1 col2 col3 col4 
ABC2 DEF2 GHI2 cond1-cond2 
ABC3 DEF3 GHI3 cond2/cond1 
ABC4 DEF4 GHI4 cond2 cond1 
ABC5 DEF5 GHI5 cond4/cond1 
ABC9 DEF9 GHI9 cond1 at 50 
ABCa DEFa GHIa con cond1 
ABCb DEFb GHIb no. cond1 
ABCc DEFc GHIc cond1 something 

File2 (chứa cond1 một mình):

col1 col2 col3 col4 
ABC1 DEF1 GHI1 cond1 
ABC6 DEF6 GHI6 cond1 

file3 (chứa bất cứ điều gì mà không được bao gồm trong file1 và file2):

col1 col2 col3 col4 
ABC7 DEF7 GHI7 mcond1 
ABC8 DEF8 GHI8 cond2 
ABCc DEFc GHIc Mcond1 

Lưu ý rằng tổng số hàng của 3 tệp giống với tệp gốc Tôi xin lỗi nếu điều này nghe khá phức tạp, nhưng đây là trường hợp tôi thực sự có.

+0

là gì mong muốn của bạn đầu ra! –

+0

Dấu phân cách giữa cột là gì? là nó tab? nếu không gian thứ 11 của hàng thứ 4 cột sẽ không chứa 'cond1'. Đó là cột thứ 5 có –

+0

Có nó là một tệp được phân tách bằng tab và đôi khi có một khoảng trắng giữa các từ. (và tôi chắc chắn nó không phải là một cột khác nhau, bởi vì đây là một tập tin lớn và tôi sử dụng cắt để có những 4 cột ra chỉ) – Error404

Trả lời

2

Vấn đề ở đây là cột 4 có không gian và tệp của bạn không được định dạng như mong đợi thử awk -F'\t' {print $4} file và nhận thấy nó có thể không phải là những gì bạn mong đợi.

Đầu tiên lần lượt các tập tin ở định dạng CSV với sed

$ sed 's/\s\+/,/;s/\s\+/,/;s/\s\+/,/;' file 
col1,col2,col3,col4 
ABC1,DEF1,GHI1,cond1 
ABC2,DEF2,GHI2,cond1-cond2 
ABC3,DEF3,GHI3,cond2/cond1 
ABC4,DEF4,GHI4,cond2 cond1 
ABC5,DEF5,GHI5,cond4/cond1 
ABC6,DEF6,GHI6,cond1 
ABC7,DEF7,GHI7,mcond1 
ABC8,DEF8,GHI8,cond2 
ABC9,DEF9,GHI9,cond1 at 50 
ABCa,DEFa,GHIa,con cond1 
ABCb,DEFb,GHIb,no. cond1 
ABCc,DEFc,GHIc,cond1 something 
ABCc,DEFc,GHIc,Mcond1 

này chỉ chuyển đổi 3 nhóm khoảng trắng đầu tiên dấu phẩy rời col4 như bạn muốn. Để lưu trữ các thay đổi trong tập tin sử dụng -i tùy chọn:

sed -i 's/\s\+/,/;s/\s\+/,/;s/\s\+/,/;' file 

Bây giờ lĩnh vực tách , có thể được sử dụng.

awk 'BEGIN{FS=",";OFS="\t"} NR==1{print $1,$2,$3,$4} $4~/cond1./|| $4~/[^mM]cond1/{print $1,$2,$3,$4}' file 
col1 col2 col3 col4 
ABC2 DEF2 GHI2 cond1-cond2 
ABC3 DEF3 GHI3 cond2/cond1 
ABC4 DEF4 GHI4 cond2 cond1 
ABC5 DEF5 GHI5 cond4/cond1 
ABC9 DEF9 GHI9 cond1 at 50 
ABCa DEFa GHIa con cond1 
ABCb DEFb GHIb no. cond1 
ABCc DEFc GHIc cond1 something 

$ awk 'BEGIN{FS=",";OFS="\t"} NR==1{print $1,$2,$3,$4} $4~/^cond1$/{print $1,$2,$3,$4}' file 
col1 col2 col3 col4 
ABC1 DEF1 GHI1 cond1 
ABC6 DEF6 GHI6 cond1 

$ awk 'BEGIN{FS=",";OFS="\t"} $4!~/cond1/ || $4~/[Mm]cond1/{print $1,$2,$3,$4}' file 
col1 col2 col3 col4 
ABC7 DEF7 GHI7 mcond1 
ABC8 DEF8 GHI8 cond2 
ABCc DEFc GHIc Mcond1 

Chỉ chuyển hướng để lưu newfiles awk '{...}' > file1.

+0

Xin chào, Cảm ơn lệnh của bạn. cho lệnh đầu tiên (sau khi chuyển nó thành tệp được phân cách bằng dấu phẩy), ngay cả khoảng cách giữa các từ được chuyển thành dấu phẩy. vì vậy tôi đã mất các trường "cond1 at 50", "cond1 something", "cond2 cond1", "con cond1" và "no. cond1". – Error404

+0

@ Error404 không lệnh 'sed' được xây dựng theo cách chỉ thay thế 3 nhóm khoảng trắng đầu tiên bằng dấu phẩy, tôi đã cập nhật câu trả lời của mình để giải thích điều này. –

+0

yes dude, Cảm ơn câu trả lời của bạn ... bây giờ tôi hiểu lệnh, tôi biết cách bắt cá và tôi sẽ ăn hàng ngày :) – Error404

1

Vì các trường của bạn được sử dụng tách nhau bằng tab FS="\t" trong khối BEGIN. Ngoài ra tình trạng của bạn là không thích hợp. Vì vậy, tôi đã thay đổi nó.

awk 'BEGIN{IGNORECASE=1; FS="\t"; } $4 ~ /cond1/ && $4 !~ /mcond1|cond1m/' data 
+0

Cảm ơn lệnh. Trên thực tế điều này là làm việc một cách tốt, nhưng tôi muốn thêm một cái gì đó để lệnh này. nếu tôi đã có điều này trong col4 "mcond1 cond1" vì vậy nếu mcond1 và cond1 là có cùng một lúc, tôi muốn nó được bao gồm, nếu mcond1 là một mình hoặc với bất cứ điều gì khác, sau đó NO. làm thế nào để tôi nói điều này? – Error404

+0

Số lần vượt quá này, bao gồm dòng 1 và 6, không có tiêu đề. –

1

Bạn có thể thực hiện tác vụ bằng một lần chuyền. Chạy như:

awk -f script.awk file 

Nội dung script.awk:

BEGIN { 
    FS="\t" 
} 

NR==1 { 
    r=$0 
    next 
} 

{ 
    i = ($4 == "cond1" ? 2 : ($4 ~ /cond1/ && $4 !~ /[Mm]cond1/ ? 1 : 3)) 
    print (!a[i]++ ? r ORS : "") $0 > "file" i ".txt" 
} 

Kết quả grep . file[1-3].txt:

file1.txt:col1 col2 col3 col4 
file1.txt:ABC2 DEF2 GHI2 cond1-cond2 
file1.txt:ABC3 DEF3 GHI3 cond2/cond1 
file1.txt:ABC4 DEF4 GHI4 cond2 cond1 
file1.txt:ABC5 DEF5 GHI5 cond4/cond1 
file1.txt:ABC9 DEF9 GHI9 cond1 at 50 
file1.txt:ABCa DEFa GHIa con cond1 
file1.txt:ABCb DEFb GHIb no. cond1 
file1.txt:ABCc DEFc GHIc cond1 something 
file2.txt:col1 col2 col3 col4 
file2.txt:ABC1 DEF1 GHI1 cond1 
file2.txt:ABC6 DEF6 GHI6 cond1 
file3.txt:col1 col2 col3 col4 
file3.txt:ABC7 DEF7 GHI7 mcond1 
file3.txt:ABC8 DEF8 GHI8 cond2 
file3.txt:ABCc DEFc GHIc Mcond1 

Ngoài ra, đây là một trong những-liner:

awk -F "\t" 'NR==1 { r=$0; next } { i = ($4 == "cond1" ? 2 : ($4 ~ /cond1/ && $4 !~ /[Mm]cond1/ ? 1 : 3)); print (!a[i]++ ? r ORS : "") $0 > "file" i ".txt" }' file 
Các vấn đề liên quan