我在 while 循环中使用“grep”(逐行读取)一个长文档(这个长文件包含多个段落,每个段落以日期/时间开头)。
目的是找到某个短语并在该短语旁边打印或回显该段落的日期/时间。当 grep 无法捕获该短语时,如何“回显”或“打印”字母“NULL”。例如:
假设文件 (test.txt) 中有这三段:
20170101,05:00 AM, I am using grep to read certain phrase1 in a long document.
20170102,09:30 AM, I am using grep to read certain phrase2 in a long document.
20170103,05:30 AM, I am using grep to read page in a long document.
如何回显或打印“某些短语”和日期时间,如果“某些短语不可用”则用 NULL 替换输出,因此输出如下:
20170101,05:00 AM,certain phrase1
20170102,09:30 AM,certain phrase2
20170103,05:30 AM,NULL
.
.
.
我使用以下内容:
while read -r line; do
date=$(grep -c "201*")
phrase=$(grep -Eo "certain phrase")
echo $date,$phrase
done < test.txt
答案1
while read -r line; do
date=$(grep -Eo "201.{12}.M," <<< "$line")
phrase=$(grep -Eo "certain phrase" <<< "$line")
echo "${date}${phrase:-NULL}"
done < test.txt
你正在阅读这句话,但并没有摸索它。我调整了第一个 grep 上的正则表达式以匹配日期部分(而不是-c
计算它)。难题的最后一部分是与 $phrase 变量相呼应参数扩展用单词“NULL”替换空值。
答案2
我建议类似的东西
awk 'BEGIN {OFS=FS=","}
/201/ {
if (match($0,"certain phrase")) {
print $1, $2, substr($0,RSTART,RLENGTH+1)
} else {
print $1, $2, "NULL"
}
}' file
使用您的输入数据进行测试:
$ awk 'BEGIN {OFS=FS=","}
> /201/ {
> if (match($0,"certain phrase")) {
> print $1, $2, substr($0,RSTART,RLENGTH+1)
> } else {
> print $1, $2, "NULL"
> }
> }' file
20170101,05:00 AM,certain phrase1
20170102,09:30 AM,certain phrase2
20170103,05:30 AM,NULL
答案3
不要grep
ping in while
,而是在一个sed
脚本中完成所有操作:
sed 's/\( *[0-9]*,[^,]*,\).*\(certain phrase[^ ]*\).*/\1\2/;t
s/\( *[0-9]*,[^,]*,\).*/\1NULL/' file.txt
sed
已经为您逐行处理,并且在每一行中,脚本都会使用以下命令执行替换s
:
第一部分[0-9]*,[^,]*,
应该与日期字符串匹配。通过用 包围它\(\)
,我们可以在替换中重用它,如下所示\1
第二个 也是如此\(\)
,包含短语和尾随非空格(如有必要,请进行调整),称为\2
。其他的一切都被扔掉了。
如果完成此替换,t
命令将跳转到脚本末尾,就像我们完成的那样。如果无法进行替换,则日期之后的所有内容都会替换为NONE
答案4
perl -lne 'print /^((?:.+?,){2})/, /\h\K(certain\h+phrase\d+)/ ? $1 : "NULL"' < test.txt
在这里,我们获取前两个逗号分隔的字段,然后查找“特定短语”。如果找到,则使用它,否则使用“NULL”。