Try the execdir
option for find
: it executes the command you specify in the directory of the file, using only its basename as the argument
From what I gather, you want to create "a" and "b" in the "main" directory. We can do that by combining $PWD
and the -execdir
option. Have a look at the solution below. (The && find … ls
parts are for output only, so you can see the effects. You'll want to use the command before the &&
.)
First, I set up the testing environment:
-----[ 15:40:17 ] (!6293) [ :-) ] janmoesen@mail ~/stack
$ mkdir test && touch test/{a,b} && find . -exec ls -dalF {} +
drwxr-xr-x 3 janmoesen janmoesen 4096 2012-05-31 15:40 ./
drwxr-xr-x 2 janmoesen janmoesen 4096 2012-05-31 15:40 ./test/
-rw-r--r-- 1 janmoesen janmoesen 0 2012-05-31 15:40 ./test/a
-rw-r--r-- 1 janmoesen janmoesen 0 2012-05-31 15:40 ./test/b
This is what happens when you use a simple -exec
— the original files are touched:
-----[ 15:40:30 ] (!6294) [ :-) ] janmoesen@mail ~/stack
$ find test -type f -exec touch {} \; && find . -exec ls -dalF {} +
drwxr-xr-x 3 janmoesen janmoesen 4096 2012-05-31 15:40 ./
drwxr-xr-x 2 janmoesen janmoesen 4096 2012-05-31 15:40 ./test/
-rw-r--r-- 1 janmoesen janmoesen 0 2012-05-31 15:40 ./test/a
-rw-r--r-- 1 janmoesen janmoesen 0 2012-05-31 15:40 ./test/b
However, if we combine $PWD
with the argument placeholder {}
and use -execdir
, we achieve what (I think) you want:
-----[ 15:40:57 ] (!6295) [ :-) ] janmoesen@mail ~/stack
$ find test -type f -execdir touch "$PWD/{}" \; && find . -exec ls -dalF {} +
drwxr-xr-x 3 janmoesen janmoesen 4096 2012-05-31 15:41 ./
-rw-r--r-- 1 janmoesen janmoesen 0 2012-05-31 15:41 ./a
-rw-r--r-- 1 janmoesen janmoesen 0 2012-05-31 15:41 ./b
drwxr-xr-x 2 janmoesen janmoesen 4096 2012-05-31 15:40 ./test/
-rw-r--r-- 1 janmoesen janmoesen 0 2012-05-31 15:40 ./test/a
-rw-r--r-- 1 janmoesen janmoesen 0 2012-05-31 15:40 ./test/b
Try:
find -iname "*.txt" -exec sh -c 'for f do basename -- "$f" .txt;done' sh {} +
Your first command failed, because $(...)
run in subshell, which treat {}
as literal. so basename {} .txt
return {}
, your find
became:
find . -iname "*.txt" -exec echo {} \;
which print file name matched.
Best Answer
My lucky guess would be that
$0
contains the string-bash
and so your command becomes:which
basename
interprets as a single-character option "b". Change that to:... so that
basename
is told to stop looking for options.