Search code examples
bashfor-loopgrepoffset

How to do a grep to match one line with an offset in a for loop


I want to get a one line grep result in a for loop and pass to the next match without all the other matches from before.

I tried the code below but it's not working as expected as I want only one line result. $nbOfMatches=7
$className=somefile

for i in $(seq 1 $nbOfMatches);
do
    lineCopy=$(grep -m $i 'private ' $className)
    echo "$lineCopy"
done

Current output :


Occurences found : 7
private $id;
private $id;
private $firstname;
private $id;
private $firstname;
private $lastname;
private $id;
private $firstname;
private $lastname;
private $email;
private $id;
private $firstname;
private $lastname;
private $email;
private $password;
private $id;
private $firstname;
private $lastname;
private $email;
private $password;
private $phone;
private $id;
private $firstname;
private $lastname;
private $email;
private $password;
private $phone;
private $address;

Expected output :

Occurences found : 7
private $id;
private $firstname;
private $lastname;
private $email;
private $password;
private $phone;
private $address;

I'd like to know if there is a way to add a offset match to the grep to remove the previous match from being detected too. Or if there is any other solution to do the expected output.


Solution

  • A simple one liner to do the trick. This will also produce the same results:

    nbOfMatches=4;grep -m$nbOfMatches private $className
    

    Also to print the string between $ ... ; you can use the sed. sed 's/.* $\(.*\);/\1/'

    nbOfMatches=4;grep -m$nbOfMatches private $className | sed 's/.* $\(.*\);/\1/'
    

    Below is a lengthy solution (if loop is mandatory). There are much elegant ways to achieve the same result.

    className="input.txt"; nbOfMatches=4; count=0; for next in `cat $className`; do var=$(echo $next | awk /private/'{print $0}'); if [ $nbOfMatches -eq $count ]; then break; fi; if [ ! -z "$var" ]; then echo "$var"; let count=$((count + 1)); fi; done
    

    This reads the specified file $className line by line and search for the pattern private. For each match it will increment the variable count. When the count becomes number of matches$nbOfMatches needed, it exit from the loop.

    Also to print the string between $ ... ;.

    className="input.txt"; nbOfMatches=4; count=0; for next in `cat $className`; do var=$(echo $next | awk /private/'{print $0}'); if [ $nbOfMatches -eq $count ]; then break; fi; if [ ! -z "$var" ]; then echo "$var"| sed 's/.* $\(.*\);/\1/'; let count=$((count + 1)); fi; done