user1488220
user1488220

Reputation:

Finding strings in a file and write to a file if found

Just wondering if someone can point me in the right direction. I want to search a file for 2 strings and if they match add a YES to a csv file or NO if they don't. For now tough I'd like to just have it find the strings and print SUCCESS on the screen if found as per below (I'd rather try get the writing to a file done myself so I learn).

I do need both strings to be a match otherwise the result should be No.

I've gotten this so far:

#/usr/bin/bash
file=test.xml
string1=TEST1
string2=TEST2
if grep -e "$string1|$string2" "$file"
then
    echo IT WORKS!!!
else
    echo UH OH!!!
fi

Upvotes: 2

Views: 677

Answers (4)

Dennis Williamson
Dennis Williamson

Reputation: 360065

Using grep you would need to read the file twice:

if grep "$string1" "$file" && grep "$string2" "$file"

However, using AWK, you can set flags and you'll only need to read the file once:

awk -v s1="$string1" -v s2="$string2" '$0 ~ s1 {f1 = 1} $0 ~ s2 {f2 = 1} END {if (f1 && f2) {print "Yes"} else {print "No"}}' "$file"

Upvotes: 1

betabandido
betabandido

Reputation: 19704

Your code is in the good direction. You need to change -e with -E in order for grep to recognize the regular expression that you are using ($string1|$string2). You may also want to avoid seeing the actual matchings (use quiet -q flag for that):

file=test.xml
string1="TEST1"
string2="TEST2"
if grep -E -q "$string1|$string2" "$file"
then
    echo IT WORKS!!!
else
    echo UH OH!!!
fi

EDIT: Since you need to match both strings, this is not possible with grep (AFAIK) unless you execute grep multiple times (like in @chepner's answer).

An alternative solution would be to use awk:

awk '/'$string1'/{s1=1}/'$string2'/{s2=1} END { \
    if (s1 && s2) print "IT WORKS!!!" ; else print "UH OH!!!" }' "$file"

Upvotes: 0

sorpigal
sorpigal

Reputation: 26086

Presuming that either string matching is sufficient, try this:

file=test.xml
string1="TEST1"
string2="TEST2"

if grep -q -F "$string1"$'\n'"$string2" "$file" ; then
    printf YES
else
    printf NO
fi

Importantly, -F means that if the string happens to contain regex-special characters they will be treated literally. For convenience -q will suppress the output of grep so you only get the YES/NO returned.

EDIT:

Since you need both strings to match, try this:

if [ $(sed -n -e "/${string1}/p;/${string2}/p" "$file" | wc -l) -ge 2 ] ; then
    printf YES
else
    printf NO
fi

This is not as safe as the grep version since regex characters in the strings are not treated literally and is rather inefficient, but it gets the job done.

Upvotes: 0

chepner
chepner

Reputation: 531135

Since you want both strings to match, an inefficient way is to call grep once for each pattern:

if grep -q "$string1" && grep -q "$string2"
then
echo IT WORKS
else
echo UH OH
fi

I'm not aware of a way to do this with a single grep call without a fairly complicated regex. Something like

grep -qE "$string1.*$string2|$string2.*$string1"

could work, but I'm sure that would include some false positives and/or false negatives, depending on the values of string1 and string2.

Upvotes: 1

Related Questions