If you are sure that the files to process are small (like your example), you can read the whole file in one go and test that:
file=$(<log3.txt)
[[ $file =~ Host ]] && [[ $file =~ denied ]] && echo "$file"
For a larger file, and assuming that Host
comes before denied
you may use a faster (for external files) sed:
<log3.txt sed -n '/^Host/!d;p;:1;n;/\<denied\>/{p;q};b1'
Understand that this solution will strictly print the first line that starts with Host
and the following (not in the same line) first line that contains denied
as a word.
If you need to extract several pairs of Host
- denied
, change the q
to a b
, that will re-start the cycle:
<log3.txt sed -n '/^Host/!d;p;:1;n;/\<denied\>/{p;b};b1'
A similar solution with awk that will print the last Host
line that is just before a denied
line (in pairs):
awk ' p==1 && /\<denied\>/ {d=$0;p=0}
/^Host*/ {h=$0;p=1}
{ if(p==0&&h!=""&&d!="") {print h,RS,d;p=2} }
' <log3.txt
And the same logic (except that it will match denied
anywhere on the line (not as a word)) in the shell:
#!/bin/sh
p=0
while IFS= read -r line; do
if [ "$p" = 1 ]; then
case $line in
*denied*) deniedline=$line; p=0 ;;
esac
fi
case $line in
Host*) hostline=$line; p=1 ;;
esac
if [ "$p" = 0 ] && [ "$hostline" ] && [ "$deniedline" ]; then
printf '%s\n%s\n' "$hostline" "$deniedline"
p=2
fi
done <log3.txt
awk
code doesn't seem to work, try withHost: denied1.com/Access denied/Host: ok.com/Access OK/Host: random.com
. The question is hard to answer since we don't know what the rest of the file looks like. – xenoid Dec 03 '18 at 09:37Host
orAccess denied
, not as pairs. The awk solution will only print the last instance of the pair. The shell solution will matchHost
at any position on the line and will only print the lastHost
and the lastAccess denied
found. – Dec 03 '18 at 21:43