Tomas Pruzina
Tomas Pruzina

Reputation: 8907

Conditional command execution within piped sequence of commands in bash

Sorry for bumpy topic name (feel free to edit if you find more fitting title after looking at problem). Code sample equals 1000 words, so here we go:

if [ "$REGEX" != "" ]; then
        find $TEST_DIR -type f -regextype posix-extended -regex '^.*(status|stderr|stdout)-captured$' |                                  
        grep -E $REGEX |
        awk '{print(""$1" "$1)}' | sed 's/-captured$/-expected/' | 
        while read -r line; do mv -f $line; done 
else
        find $TEST_DIR -type f -regextype posix-extended -regex '^.*(status|stderr|stdout)-captured$' |
        awk '{print(""$1" "$1)}' | sed 's/-captured$/-expected/' |
        while read -r line; do mv -f $line; done
fi

What code does is not all that important, I'd just like to find more elegant way to either use "grep -E $REGEX" or not. I thought that conditdonal aliases could do the job just like I'm used to from shell usage, but they does not work inside scripts.

I could put in a condition, but I fear performance impact from multiple evaluations.

Any way to make the code "more elegant"?

Upvotes: 0

Views: 932

Answers (3)

ruakh
ruakh

Reputation: 183612

One simple way is to use ^ (which always matches: it means "start-of-line", which every line has) if $REGEX is unset or blank:

find $TEST_DIR -type f -regextype posix-extended -regex '^.*(status|stderr|stdout)-captured$' |
grep -E ${REGEX:-^} |
awk '{print(""$1" "$1)}' | sed 's/-captured$/-expected/' |
while read -r line; do mv -f $line; done

For that matter, you can combine it into the original find:

find $TEST_DIR -type f -regextype posix-extended \
     -regex '^.*(status|stderr|stdout)-captured$' \
     -regex ".*${REGEX}.*" |
awk '{print(""$1" "$1)}' | sed 's/-captured$/-expected/' |
while read -r line; do mv -f $line; done

and for that matter, you can merge all of the rest of your script into find as well:

find $TEST_DIR -type f -regextype posix-extended \
     -regex '^.*(status|stderr|stdout)-captured$' \
     -regex ".*${REGEX}.*" \
     -exec bash -c 'file="{}" ; mv -f "$file" "${file%-captured}-expected"' \;

Upvotes: 1

William Pursell
William Pursell

Reputation: 212684

A very simple solution is:

test -n "$REGEX" && cmd="grep -E $REGEX"
find ... | ${cmd-cat} | awk ...

If cmd is defined, it is used in the pipe. Otherwise, cat is used, performing a no-op. You can also do:

find ... |
if test -n "$REGEX"; then
  grep -E $REGEX
else
  cat
fi |
awk ...

with exactly the same effect.

Upvotes: 1

ams
ams

Reputation: 25599

Here's a slightly ugly, but general, solution.

find $TEST_DIR -type f -regextype posix-extended -regex '^.*(status|stderr|stdout)-captured$' \
 | if [ "$REGEX" != "" ]; then
        grep -E $REGEX; \
   else \
        cat; \
   fi \
 | awk '{print(""$1" "$1)}' \
 | sed 's/-captured$/-expected/' \
 | while read -r line; do mv -f $line; done 

Upvotes: 0

Related Questions