0

I had almost the exact same question here for a windows script, but now I need to do the same in linux.

I have a script that recursively finds all .h files and checks if there is a .cpp file in the same directory with the same name. So far this works, but now I would like to use a Exclude.txt file that contains folders that should be excluded. My problem is that $file is the full path, but in Exclude.txt I want to list only the paths relative to $pwd. How can I do this?

#!/bin/bash
for file in $(find ${PWD} -name '*.h'); do 
    fileWithoutPath=$(basename $file)
    fileWithoutExtension=${fileWithoutPath%.*}
    prefix="$(dirname $file)/"
    suffix=".cpp"
    cppFile=$prefix$fileWithoutExtension$suffix

    if ??? path is not listed in ./Exclude.txt  ???   <--- what to put here?
        if [ -f "$cppFile" ]
        then
            echo "FILE EXISTS"
        else 
            echo "FILE DOES NOT EXIST"
        fi
    fi      
done

As an example:

script is in:         /u/workingDir/
Exclude has a line:   foo

then all files in /u/workingDir/foo/ should be ignored.

Community
  • 1
  • 1
463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185

4 Answers4

2

You can call a perl one-liner to convert the absolute path of $prefix to a relative path that's relative to $PWD (let's call it $relPath):

echo "$prefix" #=> /u/workingDir/foo/bar/
relPath=$(perl -e 'use File::Spec; print File::Spec->abs2rel(@ARGV) . "\n"' $prefix $PWD)
echo "$relPath" #=> foo/bar (<-- This is what you'd put into Exclude.txt)

Next, we'll use grep to check if $relPath is listed in Exclude.txt. If it is, we'll ignore that directory, and if it's not, then we'll check if $cppFile exists:

if ! grep -xqF "$relPath" ./Exclude.txt; then
   # Check for file...
   if [ -f "$cppFile" ]
      ...
   fi
else
   echo "IGNORE $relPath"
fi
seane
  • 589
  • 1
  • 4
  • 15
1
relPathToFile=${file#$PWD}      # remove $PWD from beginning
while read -r excludePath; do
    if [[ $relPathToFile == $excludePath/* ]]; then
        if [[ -f $cppFile ]]; then
            ...
    fi
 done < './Exclude.txt'
Grisha Levit
  • 8,194
  • 2
  • 38
  • 53
1

The idea: cut off the $PWD prefix, then you can grep for the result in the file.

This will cut the current directory prefix off $filename:

stripped_file=${filename##$PWD/}

An example:

$ cd /tmp
$ echo $PWD
/tmp
$ filename='/tmp/foo.txt'
$ echo ${filename##$PWD/}
foo.txt

Reuse this trick to see if a relative path includes the stripped file name:

if [ "$stripped_file_name" != "${stripped_file_name##$relative_path}" ]; then
   # hey, removing the relative path worked, so the file must be
   # on the relative path; go on.
fi

Else you might prepend $PWD to relative paths to make them absolute, and see if they are a prefix of the absolute file path.

9000
  • 39,899
  • 9
  • 66
  • 104
  • thats almost what I need. `stripped_file` still contains the file name, but I want only the (relative) path, so that I can exclude full subdirectories, and dont have to list individual files in the Exclude.txt – 463035818_is_not_an_ai Jan 25 '17 at 10:29
0

You could use readlink -f $some_file_name to get the full filename, then you could just check if the file is in the list.

Gnqz
  • 3,292
  • 3
  • 25
  • 35
  • but the full file name contains also the $pwd part and this part I do not want to list in Exclude.txt – 463035818_is_not_an_ai Jan 24 '17 at 16:10
  • Try this [exclude-directory-from-find-command](http://stackoverflow.com/questions/4210042/exclude-directory-from-find-command). The shell script can be modified to exclude files read from the exclude.txt file. – Harshdeep Sokhey Jan 24 '17 at 16:18