2013-06-05 50 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