Ducki
Ducki

Reputation: 21

Syntax for if statement in a for loop in bash

for i in $( find . -name 'x.txt' ); do; if [ grep 'vvvv' ]; 
then; grep 'vvvv' -A 2 $i | grep -v vvvv | grep -v '-' >> y.csv; else 
grep 0 $i >> y.csv; fi; done

What might be wrong with this?

Thanks!

Upvotes: 0

Views: 63

Answers (1)

Charles Duffy
Charles Duffy

Reputation: 295619

A ; is not permitted after do.

This is automatically detected by http://shellcheck.net/


That said, what you probably want is something more like:

while IFS= read -r -d '' i; do
  if grep -q -e vvvv -- "$i"; then
    grep -e 'vvvv' -A 2 -- "$i" | egrep -v -e '(vvvv|-)'
  else
    grep 0 -- "$i"
  fi
done < <(find . -name 'x.txt' -print0) >y.csv

Note:

  • Using find -print0 and IFS= read -r -d '' ensures that all possible filenames (including filenames containing spaces, newlines, etc) can be handled correctly. See BashFAQ #1 for more background on this idiom.
  • if grep ... should be used if you want if to check the output of grep. Making it if [ grep ... ] means you're passing grep as an argument to the test command, not running it as a command itself.
  • We open y.csv only once for the entire loop, rather than re-opening the file over and over, only to write a single line (or short number of lines) and close it.
  • The argument -- should be used to separate options from positional arguments if you don't control those positional arguments.
  • When - is passed to grep as a string to search for, it should be preceded by -e. That said, in the present case, we can combine both grep -v invocations and avoid the need altogether.
  • Expansions should always be quoted. That is, "$i", not $i. Otherwise, the values are split on whitespace, and each piece generated is individually evaluated as a glob, preventing correct handling of filenames modified by either of these operations.

Upvotes: 2

Related Questions