2013-06-05 29 views
8

gì là cách tốt nhất để kiểm tra xem các nội dung hoàn chỉnh của một tập tin phù hợp với một regex nhưRegex phù hợp với toàn bộ nội dung của tập tin trong bash

^[0-9]{9}$ 

tức là, chỉ 9 số và không có gì khác, không ngắt dòng và không phải nhiều bộ số.

Đây là một biến thể tôi có mà tôi không thực sự thích:

cat -vt curloutput.txt | tr "\n" " " | egrep "^[0-9]{9}$" 

Sửa

tôi sử dụng giải pháp chấp nhận như thế này:

grep --perl-regex "(?m)(?<!.)^\d{9}$(?!.)" 

sử dụng GNU grep.

+0

Bạn có nghĩa là mỗi dòng của tập tin có định dạng này hoặc là tất cả các tập tin chỉ này? – fedorqui

+0

Tất cả các tập tin nên được chỉ này. – tomsv

+0

Bạn có muốn in số, tên tệp iff khớp, y/n hoặc không in nhưng bằng giá trị thoát? – Kevin

Trả lời

5

này regex trận "bao gồm 9 chữ số" và (?m) làm caret và đô la trận đấu sau/trước dòng mới nên nó có tác dụng ngăn ngừa nhiều dòng:

(?m)(?<!.)^\d{9}$(?!.) 

Các quanh nhìn gói các trận đấu chính đảm bảo dòng khớp với nhau là chỉ có dòng trong tệp - nghĩa là có chính xác một dòng trong tệp.

Xem demonstrated on rubular này, xem như thế nào thêm bất kỳ ký tự khác để văn bản đầu vào 9 chữ số, thậm chí một dòng mới duy nhất, sẽ cho kết quả trong một trận đấu không

+0

Sẽ không hoạt động, sẽ khớp trên dòng mới đầu tiên. Một tệp chứa '123456789 \ nabce' sẽ vẫn khớp (khớp trên dòng mới đầu tiên), mà OP không muốn. – brice

+0

điều này là sai: nó chỉ kiểm tra nếu bạn có chữ số duy nhất, không phải là chỉ có 9 của họ và chỉ có 1 dòng ... –

+0

@oli câu hỏi đã được chỉnh sửa sau khi tôi đăng. Tôi nghĩ rằng tôi đã liên kết câu trả lời của tôi với câu hỏi mới. Tôi đã không có một dòng lệnh tiện dụng để kiểm tra nó. – Bohemian

6

Kiểm tra rằng linecount là 1 sau đó kiểm tra xem dòng phù hợp với regex:

test $(wc -l file.txt | cut -f 1 -d ' ') = 1 \ 
    && grep -Eq '^[0-9]{9}$' file.txt && echo "match" 

Breaking xuống lệnh, đây là những gì đang xảy ra:

#get the linecount 
wc -l file.txt | cut -f 1 -d ' ' 

# Check if there is a match in the file 
# result will be return value of the program so it can be used 
# directly with the AND operator 
grep -Eq '^[0-9]{9}$' file.txt 

Bạn thậm chí có thể hạn chế hơn bằng cách đếm bằng tes with wc:

test $(wc -c file.txt | cut -f 1 -d ' ') -eq 9 

Điều gì sẽ nhận được dòng mới, nếu cần. (-m sẽ đếm ký tự thay vào đó, trong trường hợp bạn đang sử dụng ký tự nhiều byte)

+0

sau khi gửi một câu trả lời nhanh (và sai), tôi đã xóa nó và tôi upvotting của bạn: kiểm tra rằng có 1 dòng và các dòng khớp với đầu vào sẽ chăm sóc cả hai hãy cẩn thận: không có sự lặp lại của regexp, và nó thực sự hiện tại (giải pháp "của tôi" đã xóa regexp chỉ trên dòng 1, sử dụng 'sed -e '1s/regexp //'' và kiểm tra kết quả 0 byte, nhưng tệp đầu vào 0 byte cũng sẽ khớp với các điều kiện đó ...) –

+1

Thay vì 'test -n" $ MATCH "', bạn chỉ nên sử dụng giá trị trả về grep trực tiếp: '... && grep -q ...'. – Kevin

+1

'wc -l' chỉ tính các dòng mới. Hãy tưởng tượng một tệp không có dòng mới/chỉ có một dòng và sau đó là EOF. kiểm tra 'echo -n" 123456789 ">; thử mèo | wc -l' sẽ in '0' – bartimar

1

Giả sử bạn không muốn một dòng mới trong file, đầu tiên kiểm tra kích thước tập tin sau đó kiểm tra các nội dung:

[[ $(stat -c %s $f) -eq 9 && $(<$f) =~ ^[0-9]{9}$ ]] && echo y || echo n  

thử nghiệm:

$ f=/etc/passwd 
$ [[ $(stat -c %s $f) -eq 9 && $(<$f) =~ ^[0-9]{9}$ ]] && echo y || echo n 
n 

$ f=$(mktemp) 
$ printf "123456789" >| $f 
$ [[ $(stat -c %s $f) -eq 9 && $(<$f) =~ ^[0-9]{9}$ ]] && echo y || echo n 
y 
+0

Tôi không biết về '= ~' nhờ +1 – brice

+0

Nó có thể tiện dụng, mặc dù các mẫu mở rộng tên tập tin bash khá mạnh mẽ. Một điều về bash regexes: không trích dẫn chúng hoặc nếu không chúng được coi là các chuỗi đơn giản. Có thể khá lộn xộn khi bạn kết hợp biến và regex metachars. –

1
awk 'END{if(NR == 1 && /^[0-9]{9}$/)print}' test.in 

này in số khi và chỉ khi có một cách chính xác là một dòng và nó phù hợp với mô hình.

Nếu bạn chỉ muốn giá trị trả về như grep -q, bạn có thể sử dụng này:

awk 'END{exit !(NR == 1 && /^[0-9]{9}$/)}' test.in 
+0

Awk có vẻ như là công cụ thích hợp, nhưng tôi đã thử hai lệnh của bạn và dường như không hoạt động. – brice

+0

Bạn có phiên bản awk nào? – Kevin

+0

Cả hai đều làm việc cho tôi trên cả hai gnu và BSD (mac) awks. – Kevin

1

Bạn có thể sử dụng kiểm tra tinh khiết oneliner

[[ `cat $file` =~ ^[0-9]{9}$ ]] && exit 0 || exit 1 
Các vấn đề liên quan