0

My requirement is that shell script should print the folder name of the file.

For example comp.class is present in D:/Practice/HelloWorldPractice/bin folder, I should get output after executing command is bin.

My command searches a file and prints the full path of that file . After that, it removes the filename from full path. At the end, it remove everything except folder name of file.

code

filesDirName="/D/Practice/HelloWorldSagar"
file=comp.class
echo $(find "${filesDirName}" -name ${file}) | awk -F '${file}' '{ print $1 }'| awk -F '${filesDirName}' '{ print $2 }'

output empty output

code

When I am entering below command in terminal it is working fine.... But when I am doing it through variables, I am not able to get output.

echo "$(find "/D/Practice/HelloWorldSagar" -name comp.class)" | awk -F 'comp.class' '{ print $1 }'| awk -F '/D/Practice/HelloWorldSagar' '{ print $2 }'

output

/bin/

Rui F Ribeiro
  • 56,709
  • 26
  • 150
  • 232

1 Answers1

1

Using comp.class as the field delimiter (or trying to, the variable expansion is single quoted in your code) for awk makes little sense to me, as does running multiple awk programs ofter each other in a pipeline.

As far as I understand you want the filename of the directory that contains the comp.class file.

This does that:

topdir='/D/Practice/HelloWorldSagar'
filename='comp.class'

find "$topdir" -type f -name "$filename" \
    -exec sh -c 'basename "$(dirname "$1")"' sh {} ';'

This looks for all files called comp.class in or below /D/Practice/HelloWorldSagar. When one is found, a short shell script simply prints out the base name (the filename portion of a pathname) of the directory path of the found pathname.

Alternatively, look for directories, and then separately test for the existance of the file:

find "$topdir" -type d \
    -exec test -f {}/"$filename" ';' \
    -exec basename {} ';'

This tests for existence of comp.class in all found directories under $topdir (including $topdir itself). When the file is found, the base name of the found directory is printed.

The difference between the two approaches is that the second approach would also detect a symbolic link called comp.class that points to a regular file.

Related:


Just in case it's not the base name of the directory you want, but the relative path beneath $topdir:

find "$topdir" -type f -name "$filename" \
    -exec sh -c 'd="$(dirname "$2")"; printf "%s\n" "${d#$1/}"' sh "$topdir" {} ';'

This is a variation of the first solution that extracts the directory name into a variable d, and then prints the value of that directory pathname with $topdir deleted from the start of it.

Kusalananda
  • 333,661