0

I'm trying to loop over files with having different searching conditions based on the folder which I used with a case statement. basically it's:

#!/bin/bash
case folder in
  "Testordner")
     search_filename=*_0_*.txt
      ;;
  "Ordner2")
     search_filename=*_65_*fg*.txt
     ;;
  *)
     ;;
esac
for files in $search_filename; do
  echo $files
done

I had expected to get a list of the files fitting to the search criterium in the last echo. Instead I get the search criterium itself.

For testing I tried F="*.txt";for files in $F;do echo $files;done directly in the bash (which worked and I got a list of files) and in the same script (which got me the output *.txt Already tried different variable expansion stuff (e.g. $(..) ((..)) ${..}, which all did not work.)

Why is that and how can I get around?

Would be great to find help. Best wishes Caro


using Ubuntu 22.04LTS, KDE/plasma desktop; bash v5.1.16(1). Terminal: konsole v21.12.3

3
  • 1
    how did you run the script?
    – ilkkachu
    Jul 25, 2022 at 17:39
  • using python -i script_name.py parameter or inside the interpreter using python (and then executing text)
    – Caro
    Jul 26, 2022 at 9:00
  • what? That's a shell script? Surely you're not running it with the Python interpreter?
    – ilkkachu
    Jul 26, 2022 at 9:21

1 Answer 1

1

In Bash, and with nullglob disabled (generally the default), a glob pattern will evaluate/expand to itself in the case of no matches (e.g., *.txt evaluates to the literal string *.txt). With nullglob enabled (often preferable for scripts), a glob pattern evaluates/expands to an empty string in the case of no matches.

If your script is run from different directories, your globs will expand differently (unless, of course, the same filenames exist in each of those directories).

For example:

user@host:~ 0 $ touch {a,b,c}.log
user@host:~ 0 $ ls -l
total 0
-rw-------  1 user  staff  0 Jul 25 10:27 a.log
-rw-------  1 user  staff  0 Jul 25 10:27 b.log
-rw-------  1 user  staff  0 Jul 25 10:27 c.log
user@host:~ 0 $ shopt nullglob
nullglob        off
user@host:~ 1 $ echo *.log
a.log b.log c.log
user@host:~ 0 $ echo *.bak
*.bak
user@host:~ 0 $ shopt -s nullglob
user@host:~ 0 $ shopt nullglob
nullglob        on
user@host:~ 0 $ echo *.log
a.log b.log c.log
user@host:~ 0 $ echo *.bak

user@host:~ 0 $ 

On an unrelated note... Perhaps consider habitualizing intentional quoting, at least whenever appropriate; e.g., echo "$files", as opposed to echo $files to improve command-line safety and whitespace handling.

If interested, use of arrays may also be desirable; e.g.,

#!/bin/bash -e

export PATH=/bin:/sbin:/usr/bin:/usr/sbin
shopt -s nullglob

declare -a files=()
case "$1" in
    'logs')
        files=(*.log)
        ;;
    'baks')
        files=(*.bak)
        ;;
    *)
        echo 'invalid argument' 1>&2
        exit 1
        ;;
esac

for f in "${files[@]}"; do
    echo "$f"
done

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .