我有一个文件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
不返回任何内容。我做错了什么?你有什么想法吗?
grep 的正则表达式不支持正则表达式中的s
。您可以使用grep -P (PCRE)
口味:
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
awk -F '|' '/|/ {fname=gensub(" ","","g",$1)
if ( system( "[ -f " fname " ] " ) ) {
print "D " fname }
else {
print " " fname }
}' INPUTFILE
可能适合您。
- 将输入字段分隔符设置为
|
- 仅在具有
|
s 的线路上工作 - 将
fname
变量设置为第一个字段的剥离版本 - 向外壳程序调用测试命令 (
[
)
grep -oP '|s*KS+(?=|s+OK.*CATLG)' |
while read file; do
[[ -f /myfiles/record/"$file" ]] && flag="" || flag=D
printf "%-2s%sn" "$flag" "$file"
done
解释:
- grep 命令使用 (-P) perl 正则表达式语法,并且只输出匹配的文本 (-o),每个匹配项都在自己的行上。
K
指令的意思是"忘记刚刚匹配的东西" - 这是一种获得可变长度的后视的方法。- 我发现后面跟着非空格字符:管道、空格、"OK"、一些字符和"CATLG"
- grep 输出通过管道传输到 while 循环中
- 我将文件名读入名为
file
的变量中 - 我使用条件命令
[[
和-f
运算符来查看文件是否存在。 - 如果确实存在,则执行
&&
运算符之后的命令,否则如果文件不存在,则执行||
运算符之后的命令。 - 最后,我以OP所需的格式打印输出。