如何使用正则表达式提取文件名并检查是否存在?

时间:2014-02-25 12:45:29

标签: regex bash grep

我有一个文件myfile.log,如下所示:

 RS |         hello.txt|        OK|      INFO| [CATLG]
==============================================
 A4 |        byebye.txt|        OK|      INFO| [DELETE]
==============================================
Most common:
----------------------------------------------
 AS | stackoverflow.txt|        OK|      INFO| [CATLG]

然后我尝试创建一个脚本,提取与正则表达式匹配的文件:

\s(.+)\|\s+OK\|\s+INFO\|\s+\[CATLG

最后检查/myfiles/record/目录中是否存在该文件。如果没有,将在文件名之前打印一个D.

以下是假设stackoverflow.txt存在且hello.txt不存在的输出示例:

  hello.txt
D stackoverflow.txt

我尝试使用grep函数,但如果我这样做:

grep -oh '\s.+\|\s+OK\|\s+INFO\|\s+\[CATLG' myfile.log | uniq -i

不返回任何内容。我做错了什么?你有任何想法吗?

3 个答案:

答案 0 :(得分:1)

grep的正则表达式不支持正则表达式中的\s。您可以使用grep -P (PCRE) flavor:

grep -oPh '\s.+\|\s+OK\|\s+INFO\|\s+\[CATLG' myfile.log 

或者将你的正则表达式翻译成ERE:

egrep -oh '[[:blank:]].+\|[[:blank:]]+OK\|[[:blank:]]+INFO\|[[:blank:]]+\[CATLG' myfile.log 

要打印文件名,请使用:

grep -oPh '[^|]+\|\s+\K[^|]+(?=\|\s+OK.*?\[CATLG)' file
hello.txt
stackoverflow.txt

答案 1 :(得分:0)

awk -F '|' '/|/ {fname=gensub(" ","","g",$1)
                 if ( system( "[ -f " fname " ] " ) ) {
                 print "D " fname }
                 else {
                     print "  " fname }
           }' INPUTFILE

可能会为你工作。

  1. 将输入字段分隔符设置为|
  2. 仅适用于| s
  3. fname变量设置为第一个字段的剥离版本
  4. 调出测试命令([)到shell

答案 2 :(得分:0)

grep -oP '\|\s*\K\S+(?=\|\s+OK.*CATLG)' | 
while read file; do
    [[ -f /myfiles/record/"$file" ]] && flag="" || flag=D
    printf "%-2s%s\n" "$flag" "$file"
done

说明:

  • grep命令使用(-P)perl regex语法,只输出匹配的文本(-o),每个匹配在自己的行上。
    • \K指令意味着“忘记刚刚匹配的东西” - 这是一种获得可变长度后视的方法。
    • 我发现非空格字符后面跟着:管道,空格,“OK”,一些字符和“CATLG”
  • 将grep输出通过管道传输到while循环
  • 我将文件名读入名为file
  • 的变量中
  • 我使用条件命令[[-f运算符来查看该文件是否存在。
  • 如果确实存在,则执行&&运算符之后的命令,否则如果该文件不存在,则执行||运算符之后的命令。
  • 最后,我以OP所需的格式打印输出。