Check whether files in a file list exist in a certain directory

33,370

Solution 1

The best way to iterate over the lines in a file is using the read builtin in a while loop. This is what you are looking for:

while IFS= read -r f; do
    if [[ -e $2/$f ]]; then
        printf '%s exists in %s\n' "$f" "$2"
    else
        printf '%s is missing in %s\n' "$f" "$2"
        exit 1
    fi
done < "$1"

Solution 2

The shell way, you'd write it:

comm -23 <(sort -u < "$1") <(ls -A -- "${2%/}/")

(assuming a shell with support for process substitution like ksh, zsh or bash)

comm is the command that reports the common lines between two sorted files. It displays is in 3 tab separated columns:

  1. lines only in the first file
  2. lines only in the second file
  3. lines common to both files

And you can pass -1, -2, and -3 options to remove the corresponding column.

So above, it will only report the first column: the lines that are in the file list, but not in the output of ls (ls does sort the file list by default, we assume file names in there don't contain newline characters).


In zsh, you'd use its ${A:|B} array subtraction operator:

#! /bin/zsh -
files_in_list=(${(f)"$(<$1)"})
files_in_dir=(${2%/}/*(ND:t))
print -rC1 -- ${files_in_list:|files_in_dir}
Share:
33,370

Related videos on Youtube

user29772
Author by

user29772

Updated on September 18, 2022

Comments

  • user29772
    user29772 over 1 year

    The runtime arguments are as follows: $1 is the path to the file containing the list of files $2 is the path to the directory containing the files What I want to do is check that each file listed in $1 exists in the $2 directory

    I'm thinking something like:

    for f in 'cat $1'
    do
    if (FILEEXISTSIN$2DIRECTORY)
    then echo '$f exists in $2'
    else echo '$f is missing in $2' sleep 5 exit
    fi
    done
    

    As you can see, I want it so that if any of the files listed in $1 don't exist in the directory $2, the script states this then closes. The only part I can't get my head around is the (FILEEXISTSIN$2DIRECTORY) part. I know that you can do [ -e $f ] but I don't know how you can make sure its checking that it exists in the $2 directory.

  • user29772
    user29772 over 11 years
    Thank you, I haven't really used while loops or the read function yet, so I will play around with this.
  • jordanm
    jordanm over 11 years
  • user29772
    user29772 over 11 years
    Is the IFS= part necessary if the files in the list are just separated by white space (the file names contain no spaces :) )
  • Stéphane Chazelas
    Stéphane Chazelas over 11 years
    Putting it in a more sensible way, omitting IFS= is only necessary when you want leading and trailing blanks to be stripped from the beginning and end of the lines being read. It makes no sense to omit it otherwise.