LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   getting directory in bash script (https://www.linuxquestions.org/questions/programming-9/getting-directory-in-bash-script-590092/)

firsttux 10-07-2007 01:13 PM

getting directory in bash script
 
Hello,

I'm new in linux programming. I would like to write a script that will search for a specific file eg. test.txt .... This file si located in directory /home/user/1/test.txt, /home/user/2/test.txt ...

For searcing the files I'm using

FILE=$(find /home -iname '*.txt') -> When I echo $FILE, I get eg. /home/user/1/test.txt

Now I would like to get a folder under /home/user eg. 1, 2, 3, in an echo commadn without /home/user/ and file name eg.


File test.txt is in directory 1
File test.txt is in directory 2

Thanks for your answares

MS3FGX 10-07-2007 02:09 PM

The easiest thing would be to just use the command "basename":

Code:

basename $FILE
To do the opposite (show directory rather than the file) use "dirname".

druuna 10-07-2007 02:11 PM

Hi,

Have a look at this:

find /home/ -iname '*.txt' | awk -F"/" '{ print "File " $4 " is in dir " $3 }'

This doesn't use the FILE=$(...) construct, all found by the find command is given to awk, which prints the relevant parts (fields 3 and 4 id the separator is set to /).

The | between the find and the awk command is called a pipe. This can be used to give the output of one command to the input of another command.

There are other ways to solve your problem, but if you do not need the output of the find command elsewere, there's no need to store it in a variable first.

Hope this helps.

matthewg42 10-07-2007 05:33 PM

Using find will probably return many results, not just one. If you want to perform some operation on each file found, you can do it like this:
Code:

find /home/ -iname '*.txt' |while read filename; do ... done
Where ... are the operations you wish to perform for each file found.

On the other hand, if you want to stop searching after the first file has been located, you can do it like this:
[CODE]find /home/ -iname '*.txt' -print -quit[CODE]
This is a good idea considering how long find can take on large directory structures.

Using basename is OK, but it invokes an external program, which means it is slow / will cause more system load, particularly if you have a lot of files you are interested in. Instead you can use some shell variable expansions to extract parts of the string. In this example. basename1 and basename2 will contain the same result, but the operation used to get basename2 is much faster. The same applies to dirname1 and dirname2.
Code:

mypath="/home/matthew/1/file.txt"
basename1=$(basename "$mypath")
basename2=${mypath##*/}

dirname1=$(dirname "$mypath")
dirname2=${mypath%/*}

You can find detailed descriptions of these and other variable expansions in the "Parameter Expansion" section of the bash manual page.

In summary, a good way to achieve what you describe in the second part of your OP is:
Code:

find /home -iname '*.txt' | while read f
do
    b=${f##*/}
    d=${f%/*}
    echo "File $b is in directory ${d##*/}"
done


ghostdog74 10-08-2007 01:07 AM

Code:

find /home -iname '*.txt' -printf "%h\n" | awk -F"/" '{print $NF}'


All times are GMT -5. The time now is 09:50 PM.