5

I am trying to manipulate the filename from the find command:

find . -name "*.xib" -exec echo '{}' ';'

For example, this might print:

./Views/Help/VCHelp.xib

I would like to make it:

./Views/Help/VCHelp.strings

What I tried:

find . -name "*.xib" -exec echo ${'{}'%.*} ';'

But, the '{}' is not being recognized as a string or something...


I also tried the following:

find . -name "*.xib" -exec filename='{}' ";" -exec echo ${filename%.*} ";"

But it is trying to execute a command called "filename" instead of assigning the variable:

find: filename: No such file or directory

1
  • 1
    I edited answer to explain why you can't simply use -exec filename='{}' ";", please make sure you read it. Commented Nov 26, 2012 at 11:33

3 Answers 3

7

You can't use Parameter Expansion with literal string. Try to store it in a variable first:

find . -name '*.xib' -exec bash -c "f='{}' ; echo \${f%.xib}.strings" \;

-exec sees first argument after it as the command, therefore you can't simply give it filename='{}' because find doesn't use sh to execute what you give it. If you want to run some shell stuff, you need to use sh or bash to wrap up.

Or use sed:

find . -name '*.xib' | sed 's/.xlib$/.strings/'
Sign up to request clarification or add additional context in comments.

6 Comments

Perfect, I wanted to understand why my trials failed. Thanks.
Of course, your first method fails miserably if a file name contains a single quote.
Also, try to touch $'lol.xib\nnotfunny.xib' and see what happens... here both methods fail miserably. I hope this will not be used in production scripts.
@gniourf_gniourf If there is really a production environment for allowing those characters in filenames, then just save a script echo "${1%.xib}.strings" and run with -exec ./script '{}' \;.
@livibetter yes! or you can use globstar and get rid of the find altogether for such simple searches.
|
2

For such a simple search, you can use a pure bash solution:

#!/bin/bash

shopt -s globstar
shopt -s nullglob

found=( **.xib )

for f in "${found[@]}"; do
   echo "${f%xib}strings"
done

Turning the globstar shell option on enables the ** to "match all files and zero or more directories and subdirectories" (as quoted from the bash reference manual). The nullglob option helps if there's no match: in this case, the glob will be expanded to nothing instead of the ugly **.xib. This solution is safe regarding filenames containing funny characters.

Comments

1
find . -name "*.xib" | sed -e 's/\.xib$/.strings/'

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.