68

I have an directory, which has a lot of subdirectories. those subdirs sometimes even have subdirs. there are source files inside.

How could I use genstrings to go across all these dirs and subdirs?

Let's say I cd to my root dir in Terminal, and then I would type this:

genstrings -o en.lproj *.m

How could I tell it now to look into all these directories? Or would I have to add a lot of relative paths comma separated? how?

Douwe Maan
  • 6,888
  • 2
  • 34
  • 35
dontWatchMyProfile
  • 45,440
  • 50
  • 177
  • 260

13 Answers13

113

One method would be:

find ./ -name "*.m" -print0 | xargs -0 genstrings -o en.lproj

xargs is a nice chunk of shell-foo. It will take strings on standard in and convert them into arguments for the next function. This will populate your genstrings command with every .m file beneath the current directory.

This answer handels spaces in the used path so it is more robust. You should use it to avoid skipping files when processing your source files.

Edit: as said in the comments and in other answers, *.m should be quoted.

Jaroslav
  • 1,389
  • 14
  • 27
Brian King
  • 2,834
  • 1
  • 27
  • 26
  • This isn't working for me, but the answer from SEG below did work out ok (there's a backslash before *.m). – Martin Jan 28 '13 at 15:44
  • 8
    Don't forget that when typing this in the shell, `*.m` needs to be quoted (i.e. `find ./ -name "*.m" ...`) because otherwise the shell will try to expand it first – user102008 Jun 26 '13 at 07:55
  • @Lance then you have no '.m' files in the current directory when you run it, and so the shell substitution is failing. Escaping the pattern will let this work regardless of the contents of the current directory. – rvalue May 06 '14 at 02:47
  • 2
    I found how to make it run on Swift file. just replace the *.m with *.swift should do it. It seems to parse swifts version of the command ie. NSLocalizedString("mykey", comment: "comment"); – j2emanue Mar 26 '15 at 23:50
  • @Brian King Do you know if there's a possibility to also output something like `/* File1.m */` as soon as a new file is accessed? In order to be able to better group the localized strings into files. – emmics Mar 25 '20 at 16:07
93

I don't know exactly why, but Brian's command didn't work for me. This did:

find . -name \*.m | xargs genstrings -o en.lproj

EDIT: Well, when I originally wrote this I was in a hurry and just needed something that worked. The issue that was occurring for me when using the accepted answer above was that "*.m" has to be quoted (and the curious can find an explanation as to why this is the case in the comments on Brian King's answer). I think that the best solution is to use that original answer with the appropriate bit quoted, which would then read:

find ./ -name "*.m" -print0 | xargs -0 genstrings -o en.lproj

I'm leaving my original reply intact above though, in case it still helps anybody for whatever reason.

Jonathan Zhan
  • 1,883
  • 1
  • 14
  • 17
19

This works for me:

find ./ -name \*.m -print0 | xargs -0 genstrings -o en.lproj

Thanks to Brian and Uberhamster.

SEG
  • 1,717
  • 1
  • 18
  • 33
7

Swift

find ./ -name \*.swift -print0 | xargs -0 genstrings -o en.lproj

If you need the file in same folder

find ./ -name \*.swift -print0 | xargs -0 genstrings -o .
Sorin Lica
  • 6,894
  • 10
  • 35
  • 68
anoop4real
  • 7,598
  • 4
  • 53
  • 56
6

Not sure if anyone noticed it or the option came later on, but now there is an -a option is genstrings. None of the above options worked for me. Below is my solution.

find ./ -name "*.m" -exec echo {} \; -exec genstrings -a -o en.lproj {} \;

This will also print the name of the files read.

Though above command works fine, it was not exactly for me, because in my project folder there are many files which are lying in folder but not included in xcode project. So what I did was, created a list of files used in my project by parsing pbxproj file. Added the list in filelist.txt, and fired below command

while read f; do find ./ -name "$f" -exec echo {} \; -exec genstrings -a -o en.lproj {} \; ; done < filelist.txt
JOA80
  • 527
  • 3
  • 13
  • This should be accepted)) It covers even sophisticated folder structure . Thanks @Ashishail – Roma Sep 21 '15 at 11:12
6

Since no one has posted a solution with both Objective-C and Swift, I though I'd share how I do it.

find ./ -name "*.swift" -print0 -or -name "*.m" -print0 | xargs -0 genstrings -o en.lproj

By using this your localizable strings file will be replaced with strings from both the swift and objective-c files.

Edit: You need to cd to the directory with all your subdirectories.

Matt
  • 1,599
  • 14
  • 14
5

I just added another path to the genstrings command, like this:

genstrings -o en.lproj *.m Classes/*.m

..and it worked out fine!

Mani
  • 1,597
  • 15
  • 19
  • Works, but it doesn't check for duplicate entries from each specified directory. I got a duplicate entry in .strings file with same key and comment. I guess it works like -a flag. – Hlung Mar 26 '12 at 11:04
  • 2
    @Emmanuel that is correct. The -a flag doesn't append new strings-- it appends ALL strings to an existing Localizable.strings file. – codeperson Sep 04 '12 at 22:37
3

I a have a lot of code in .mm files so i have to use:

find . -name \*.m -or -name \*.mm | xargs genstrings

or other variants, such as

find . -name \*.m -or -name \*.mm | xargs -0 genstrings -o en.lproj
Rok Jarc
  • 18,765
  • 9
  • 69
  • 124
2

The following improves on the earlier answers, this will find both .h and .m files:

find ./ -name *.h -print0 -o -name *.m -print0 | xargs -0 genstrings -o en.lproj
cbartel
  • 1,298
  • 1
  • 11
  • 18
1

I had problems generating the strings file for a folder structure where some of the folders had spaces in their names.

I found a nice solution on this site: http://riveroften.com/generate-localizable-strings-file-with-genstrings/

find . -name "*.m" -print0 | xargs -0 genstrings -o "en.lproj"
raliz
  • 81
  • 5
1

To scan all the .m files: in root folder run this

genstrings ./**/*.m

0

find ./ -name "*.m" -print0 | xargs -0 genstrings -o en.lproj

This will populate your genstrings command with every .m file to the current directory. Than create the NSLocalizedString() "key/context" in the Localizable.string file, which can be used any where in the project.

0

Try this

genstrings -o English.lproj ./Classes/*.m ./Classes/*.h ./Classes/subclass/*.m

If subfolders aren't too much, this will work perfectly.

puchikon
  • 92
  • 10