For loops to iterate through only those files that are available

Say I have monthly data files for Jan 2020 and all of 2019 and I want to loop through all the available months to perform some action. This is my closest attempt

for month in {01..12}; do
    for year in 2019 2020; do
        cat this_file-${year}-${month} | grep this_word -i
    done
done

It works in the sense that I can see the output for 13 months, but then also returns "no such file or directory" for all the months in 2020 except Jan (because that's the only month I have the data file for in 2020), which makes copying output directly from the terminal a pain. Any pointers?

Because I run my commands on the shell, a one liner solution would be perfect.

3 answers

  • answered 2020-02-12 23:09 Wiimm

    try this:

    for month in {01..12}; do
        for year in 2019 2020; do
            f="this_file-${year}-${month}"
            [[ -f $f ]] && grep this_word -i "$f"
        done
    done
    

    There is no need to use cat "$f" and a pipe.

  • answered 2020-02-12 23:09 wjandrea

    The simplest fix is to just check if the file exists:

    for month in {01..12}; do
        for year in 2019 2020; do
            file="this_file-${year}-${month}"
            if [[ -f $file ]]; then
                grep this_word -i "$file"
            fi
        done
    done
    

    Also you don't need cat when grep can open the file itself.

  • answered 2020-02-12 23:15 Freddy

    With brace expansion you could do:

    grep -i 'this_word' file-{2019..2020}-{01..12} 2>/dev/null
    

    The error messages are suppressed by redirecting stderr to /dev/null.