2012-05-19 58 views
7

Tôi có một tệp chứa một số từ trong dấu ngoặc đơn. Tôi muốn biên soạn một danh sách tất cả những lời độc đáo xuất hiện ở đó, ví dụ:Làm cách nào để tìm tất cả các từ xuất hiện giữa dấu ngoặc đơn?

This is some (text). 
This (text) has some (words) in parenthesis. 
Sometimes, there are numbers, such as (123) in parenthesis too. 

Đây sẽ là danh sách kết quả:

text 
words 
123 

Làm thế nào tôi có thể liệt kê tất cả các mục xuất hiện giữa dấu ngoặc đơn?

Trả lời

17

Bạn có thể sử dụng awk như thế này:

awk -F "[()]" '{ for (i=2; i<NF; i+=2) print $i }' file.txt

bản in:

text 
text 
words 
123 

Bạn có thể sử dụng một mảng để in các giá trị duy nhất:

awk -F "[()]" '{ for (i=2; i<NF; i+=2) array[$1]=$i; print array[$1] }' file.txt

in:

text 
words 
123 

HTH

+0

Như thế này thật tao nhã. Dấu ngoặc đơn không cân bằng sẽ thất bại, tuy nhiên, vì nó thực sự chỉ sử dụng dấu ngoặc đơn làm dấu phân tách. '"1) Xem nếu (này) (từ) bị bắt"' In 'Xem nếu' –

3

grep -oE '\([[:alnum:]]*?\)' | sed 's/[()]//g' | sort | uniq

  • -o Chỉ in các văn bản phù hợp
  • -E phương tiện sử dụng biểu thức thông thường kéo dài
  • \( phương tiện phù hợp với một paren đen
  • [[:alnum:]] là tính chất giai cấp POSIX cho chữ và số.

Kịch bản sed này sẽ loại bỏ các dấu ngoặc đơn. Điều này được thử nghiệm chống lại GNU grep, nhưng BSD sed rất cảnh giác.

+0

Tôi cần gắn cờ 'g' toàn cục vào cuối lệnh sed của mình, nhưng nếu không thì nó sẽ hoạt động. – chrisaycock

+0

Đó là những gì tôi nhận được để nhập và không sao chép! – mkb

2

Sao chép danh sách của bạn:

cat file.txt | sed 's/.*(\(.*\)).*/\1/' 

Để biên soạn một danh sách các từ duy nhất, bạn cần phải xử lý danh sách hơn nữa:

cat file.txt | sed 's/.*(\(.*\)).*/\1/' | sort | uniq 
+2

Điều này sẽ không hoạt động trên một câu có chứa nhiều hơn một '(từ)'. sed sẽ chỉ tìm thấy một trận đấu. – chrisaycock

+0

bạn có thể sửa lỗi này, vì điều này sẽ không hoạt động trên các câu như được đề xuất bởi @chrisaycock –

+0

@VenkatMadhav Câu trả lời được chấp nhận từ steve hoạt động tốt. –

5

Với GNU grep, bạn có thể sử dụng một perl regex tương thích với các xác nhận xung quanh để loại trừ các parens:

grep -Po '(?<=\().*?(?=\))' file.txt | sort -u 
+0

+1 Tôi biết điều này có thể được thực hiện bằng grep tốt. Thêm các loại phân loại và uniq cho tính nhất quán – Steve

+1

@steve, tôi thấy 'sort | uniq' của bạn và nâng bạn lên' sort -u' –

1

Bạn có thể thử

sed -e 's/\(/\n\(/g' -e 's/\)/\n/g' filename|awk -F'(' '{print $2}'|sort -u 

Explaination này:

The 1st sed tuyên bố đặt các từ trong ngoặc đơn trong dây chuyền mới và sed thứ hai thay thế nhân vật ')' với dòng mới.Vì vậy, sau khi chạy lệnh dưới đây

sed -e 's/\(/\n\(/g' -e 's/\)/\n/g' filename 

đầu ra sẽ trông như thế này

This is some 
(text 
.This 
(text 
has some 
(words 
in parenthesis. 
Sometimes, there are numbers, such as 
(123 
in parenthesis too. 

Bây giờ đường ống đầu ra này xuống dưới tuyên bố awk mà in từ thứ hai giữa các nhân vật lọc '('

awk -F'(' '{print $2}' 

kết quả hiện tại sẽ là

text 
text 
words 
123 

đầu ra ở trên được đặt theo đường ống để sắp xếp lệnh -u để cung cấp các từ duy nhất từ ​​đầu ra ở trên. Hy vọng lời giải thích này sẽ hữu ích.

+0

hãy giải thích câu trả lời của bạn một chút ... –

+0

@AK_ chỉnh sửa câu trả lời của tôi với lời giải thích. Hy vọng rằng sẽ giúp và bỏ phiếu cho câu trả lời nếu bạn hài lòng. –

+0

+1 bây giờ là một câu trả lời tốt bằng văn bản của nó. –

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