tcsh check if file exists in a given path

user3295674 picture user3295674 · Mar 5, 2015 · Viewed 26.8k times · Source

First of all, I am new to tcsh and I realize its disadvantages and why it is harmful (and I agree!).

However, I don't have a choice and I am needing to write a tcsh script where the user provides a directory as input and the script will check if it has the file 'test.txt' in it.

The child directory would also technically be labeled as having it.

I'm assuming this will need recursion and I know to check if a file exists and is a regular file I can use

if ( ! -d $1) then
    echo $1 "is not a directory."
    exit 1
endif

if ( -f test.txt ) then    #BUT LINK IT TO $1, as if test.txt exists in 
                           #given user path or its parent directories

     echo "The path includes the file."
else
     echo "The path does NOT include the file."
endif

I want it to be able to have it check $1 (which will be user input).

Answer

Martin Tournoij picture Martin Tournoij · Mar 5, 2015

You can use a simple while loop:

# Expand parameter to full path
set dir = `readlink -f "$1"`

# Not a directory? Stop now
if ( ! -d "$dir" ) then
    echo "$dir is not a directory."
    exit 1
endif

# Loop forever
while (1)
    # Check if $dir has test.txt, if it does, stop the loop
    if ( -f "$dir/test.txt" ) then
        echo "The path $dir includes the file."
        break
    else
        echo "The path $dir does NOT include the file."
        # Dir is /, we've checked all the dirs, stop loop and exit
        if ( "$dir" == "/" ) then
            echo "file not found, stopping"
            exit 2
            break
        endif

        # Remove last part of $dir, we use this value in the next loop iteration
        set dir = `dirname "$dir"`
    endif
end

echo "File found at $dir/test.txt"

The logic should be fairly obvious: You change the value of $dir for every iteration of the loop, if we've find the file, we can stop the loop, if we've looped to the / dir, the file doesn't exist and we stop. You can of course change / to cwd or something else...

Example output:

[~]% csh checkdir.csh test/asd/asd/asd/asd/
The path /home/martin/test/asd/asd/asd/asd does NOT include the file.
The path /home/martin/test/asd/asd/asd does NOT include the file.
The path /home/martin/test/asd/asd does NOT include the file.
The path /home/martin/test/asd does NOT include the file.
The path /home/martin/test does NOT include the file.
The path /home/martin does NOT include the file.
The path /home does NOT include the file.
The path / does NOT include the file.
file not found, stopping
Exit 2

[~]% touch test/asd/asd/asd/test.txt
[~]% csh checkdir.csh test/asd/asd/asd/asd
The path /home/martin/test/asd/asd/asd/asd does NOT include the file.
The path /home/martin/test/asd/asd/asd includes the file.
File found at /home/martin/test/asd/asd/asd/test.txt

[~]% rm test/asd/asd/asd/test.txt
The path /home/martin/test/asd/asd/asd/asd does NOT include the file.
The path /home/martin/test/asd/asd/asd does NOT include the file.
The path /home/martin/test/asd/asd does NOT include the file.
The path /home/martin/test/asd does NOT include the file.
The path /home/martin/test does NOT include the file.
The path /home/martin includes the file.
File found at /home/martin/test.txt