I'm struggling with escaping and expression evaluation.  I am trying to run a command inside a find...-exec COMMAND structure, where COMMAND operates on one file and outputs to the stdout.  To use this COMMAND normally on the command line, I simply redirect to a new file, like this:COMMAND inputfilename.md > outputfilename.md.confThis works fine.  However, if I want to recursively loop over ALL the files in a directory and its subdirectory, using find -exec, I can't seem to figure out how to separate the file name and the path so that I can redirect properly.  For example, this produces an error:find ./ *.md -not -path './/.git/*' -exec COMMAND '{} > ~/wiki/newdirectory/{}.cong' \;because {} expands the entire file path.  I've tried various combinations of basename and dirname, but I can't seem to get them to evaluate (instead, I just get the string 'basename' etc.). For example, this didn't work, because the text 'basename' just shows upfind ./ *.md -not -path './/.git/*' -exec COMMAND  '{} > ~/wiki/newdirectory/''basename {}''.conf' \;(returns this error: 'No such file or directory - .//newdirectory/README.md.conf > ~/wiki/newdirectory/basename .//newdirectory/README.md.conf').Any help would be appreciated.  To summarize, the objective is:Recursively iterate over all files matching *.md in a directoryExecute COMMAND inputfile.md > ~/newdirectory/inputfile.md.conf where inputfile is the same string in each iteration.Thanks!
Separate filename and path inside find command's -exec option
bash;find
Whatever you do, you'll need to invoke a shell to perform the redirection of the command output to a file whose location depends on the find result.find ./ *.md -not -path './/.git/*' -exec sh -c 'COMMAND $0 > ~/wiki/newdirectory/${0##*/}.cong' {} \;Don't substitute {} inside the shell script. This isn't supported on all systems, and even where it is, that would not work in general, since it would treat the file name as a piece of shell syntax, e.g. a file called ;rm -rf ~;.md would cause you to erase all your files.${0##*/} uses pure string manipulation to obtain the base name of the file. You could also use $(basename -- $0).