Bash: using commands as parameters (specifically cd, dirname and find)
-
20-09-2019 - |
Question
This command and output:
% find . -name file.xml 2> /dev/null
./a/d/file.xml
%
So this command and output:
% dirname `find . -name file.xml 2> /dev/null`
./a/d
%
So you would expect that this command:
% cd `dirname `find . -name file.xml 2> /dev/null``
Would change the current directory to ./a/d. Strangely this does not work. When I type cd ./a/d
. The directory change works. However I cannot find out why the above does not work...
Solution
Just noticed the backticks... use this instead:
cd $(dirname $(find . -name file.xml 2> /dev/null))
edit: with the arguments quoted (in case they contain white space):
cd "$(dirname "$(find . -name file.xml 2> /dev/null)")"
OTHER TIPS
you can use find
's -execdir
option as well
-execdir command {} +
Like -exec, but the specified command is run from the subdirectory containing the matched file, ....
so there's no need to cd
Use the '$(...)' notation as in @fortran's answer. If you must use back-ticks, then you have to escape the nested ones:
cd `dirname \`find . -name file.xml 2> /dev/null\``
It gets really hairy when you want to change to the lib directory for your current version of Perl, for example.
Easy
cd $(dirname $(dirname $(which perl)))/lib
Hard
cd `dirname \`dirname \\\`which perl\\\`\``/lib
That's why the '$(...)' notation is preferrable.
Note that you can write this with one less level of backticks using find -exec
:
cd `find . -name file.xml -exec dirname {} \;`
Or alternatively using GNU find's -printf
action:
cd `find . -name file.xml -printf %h`