2013-06-05 51 views
8

什麼是測試如果一個文件的完整內容的正則表達式匹配的最佳方式,如正則表達式匹配的bash文件的全部內容

^[0-9]{9}$ 

即,只有9號,沒有別的,沒有換行符,而不是多組數字。

這是一個變種我有我真的不喜歡:

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

編輯

我用的是接受的解決方案是這樣的:

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

使用GNU的grep。

+0

你指的是具有這種格式的文件的每一行或是所有的文件嗎? – fedorqui

+0

所有的文件應該是這個。 – tomsv

+0

是否要打印數字,文件名如果匹配,是/否,還是不打印,但按退出值打印? – Kevin

回答

5

此正則表達式匹配「由9位數字」和(?m)使插入符號和美元賽後/換行符之前,因此它可以防止多行:

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

外觀變通包裝的主要比賽保證線路匹配的是文件中的只有行 - 即文件中只有一行。

見本demonstrated on rubular,看看如何添加任何其他字符到9位數字輸入文本,即使是單個換行,將導致非匹配

+0

不起作用,將匹配第一個換行符。包含'123456789 \ nabce'的文件仍然匹配(匹配第一個換行符),OP不需要。 – brice

+0

這是錯誤的:它只是檢查你是否只有數字,而不是隻有9個,只有1行... –

+0

@oli問題在我發佈後編輯。我想我已經將我的答案與新問題結合起來。我沒有一個方便測試它的命令行。 – Bohemian

6

測試該linecount是1,那麼測試該線相匹配的正則表達式:

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

打破了命令,這是發生了什麼事:

#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 

你可以更嚴格由計數tes with wc:

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

如果需要的話,它將捕獲尾隨換行符。 (-m將計算字符,而不是,如果你正在使用多字節字符)

+0

提交一個快速鞭打(和錯誤)的答案後,我刪除它,我upvotting你的:檢查有1行和該行匹配輸入需要注意的兩個警告:沒有重複的正則表達式,而且它實際上目前(我的「解決方案」只刪除了第一行的正則表達式,使用'sed -e'1s/regexp //''並檢查了0字節的結果,但0字節的輸入文件也符合這些條件... ) –

+1

而不是'test -n「$ MATCH」',你應該直接使用grep返回值:'... && grep -q ...'。 – Kevin

+1

'wc -l'只計算換行符。設想一個沒有換行的文件/只有一行,然後是EOF。 'echo -n「123456789」> test;貓測試| wc -l'將會打印出'0' – bartimar

1

假設你想在文件中不換行,首先檢查文件的大小,然後檢查內容:

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

測試:

$ 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

我不知道'=〜'謝謝+1 – brice

+0

雖然bash文件名擴展模式也非常強大,但它可以很方便。關於bash正則表達式的一點是:不要引用它們,否則將它們視爲純字符串。將變量和正則表達式組合在一起時會變得非常混亂。 –

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

這將打印數當且僅當有一個精確的線和它匹配的模式。

如果你只是想喜歡grep -q的返回值,你可以使用這個:

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

Awk看起來是合適的工具,但我剛剛嘗試過你的兩個命令,而且都不起作用。 – brice

+0

你有什麼awk版本? – Kevin

+0

在gnu和BSD(mac)awks上都適用於我。 – Kevin

1

您可以使用純測試oneliner

[[ `cat $file` =~ ^[0-9]{9}$ ]] && exit 0 || exit 1