velo9
velo9

Reputation: 2335

Simplest Bash code to find what files from a defined list don't exist in a directory?

This is what I came up with. It works perfectly -- I'm just curious if there's a smaller/crunchier way to do it. (wondering if possible without a loop)

files='file1|file2|file3|file4|file5'
path='/my/path'

found=$(find "$path" -regextype posix-extended -type f -regex ".*\/($files)")

for file in $(echo "$files" | tr '|', ' ')
do
    if [[ ! "$found" =~ "$file" ]]
    then
        echo "$file"
    fi
done

Upvotes: 0

Views: 93

Answers (4)

user unknown
user unknown

Reputation: 36229

without whitespace in filenames:

files=(mbox todo watt zoff xorf)
for f in ${files[@]}; do test -f $f || echo $f ; done 

Upvotes: 0

Gergo Erdosi
Gergo Erdosi

Reputation: 42048

You can do this without invoking any external tools:

IFS="|"
for file in $files
do
    [ -f "$file" ] || printf "%s\n" "$file"
done

Upvotes: 1

kev
kev

Reputation: 161664

$ eval "ls $path/{${files//|/,}} 2>&1 1>/dev/null | awk '{print \$4}' | tr -d :"

Or use awk

$ echo -n $files | awk -v path=$path -v RS='|' '{printf("! [[ -e %s ]] && echo %s\n", path"/"$0, path"/"$0) | "bash"}'

Upvotes: 0

bitmask
bitmask

Reputation: 34628

Your code will break if you have file names with whitespace. This is how I would do it, which is a bit more concise.

echo "$files" | tr '|' '\n' | while read file; do
  [ -e "$file" ] || echo "$file"
done

You can probably play around with xargs if you want to get rid of the loop all together.

Upvotes: 0

Related Questions