LearnerCode
LearnerCode

Reputation: 179

BASH: Using a continue in a for loop

As this is for work, I am unable to show my real example; but will a dummy example to explain my issue. I have a BASH script that runs the following command:

for name in $HOME/data/individual-*-lookup; do
    $name
done

However if name equals a certain attribute (e.g. John). I want the for loop to skip over this name. I have tried the following code; but it still seems to run all the options:

#! /bin/bash

for name in $HOME/data/individual-*-lookup; do  
    if ["$name" == "$HOME/data/individual-john-lookup"]; then
        continue
    fi
    $filename

done

Upvotes: 2

Views: 5483

Answers (1)

Léa Gris
Léa Gris

Reputation: 19545

A few issues I fixed in your code:

  • Line 3, missing quotes around $HOME, to prevent the value to be parsed as multiple words, if it contains characters of the $IFS environment variable.
    (See: ShellCheck: SC2231):

    for name in $HOME/data/individual-*-lookup; do
               ^     ^
               "$HOME"/data/individual-*-lookup
    
  • Line 4, missing spaces inside the test brackets:

    if ["$name" == "$HOME/data/individual-john-lookup"]; then
        ^                                            ^
    
  • Line 4, mixed single bracket [ condition ] POSIX syntax and == Bash string equality syntax

    if ["$name" == "$HOME/data/individual-john-lookup"]; then
       ^        ^^                                    ^
    
  • Line 7, missing double quotes " around $filename

     $filename
    ^         ^
     "$filename"
    

Fixed refactored version:

#!/usr/bin/env bash

filename=() # Array of a command with its parameters

for name in "$HOME"/data/individual-*-lookup; do
  # Continue to next name if file is physically same,
  # regardless of path string syntax
  [[ $name -ef "$HOME/data/individual-john-lookup" ]] && continue
  filename=(: "$name") # Command and parameters ":" is a dummy for command name
  "${filename[@]}"     # Run the command with its parameters
done

Test the -ef comparison to check the file is physically the same rather than string equality, so if file path expands with slight syntax differences, it does not matter.

The -ef condition operator is a Bash feature:

FILE1 -ef FILE2 True if file1 is a hard link to file2.

Since there is only one statement after the test, the shorter test && command can be used, in-place of if test; then; command; fi

The $filename command call is replaced by a "${filename[@]}" array for much better flexibility into adding arguments dynamically.

Upvotes: 5

Related Questions