Search code examples
xcodesedreplacemultilinecarriage-return

Find and replace over multiple lines using sed in Xcode Run Script bin/sh


I have a Cocos2D tmx file which is very much like an xml and includes carriage returns and spaces.

My requirements are:

In every tmx file in Resources/maps_sideScrolling/

find and everything between

<tileset firstgid="1"

and the first occurring

<layer name="background"

and replace with the contents of Resources/maps_sideScrolling/tileProperties.txt

I've tried the following with no result. The problem is caused by the string to be searched has multiple lines.

sed -i '' 's{<tileset firstgid="1.*<layer name="background"{Resources/maps_sideScrolling/tileProperties.txt{g' Resources/maps_sideScrolling/*.tmx;

Here's a pastebin of the tmx snippet that I want to edit: http://pastebin.com/wr39zj1r


Solution

  • Geek uses python to do this kind of thing to TMX map files. Just an option to consider.

    Something like this (but iterating all files in directory etc), and save it as a .sh file:

    #!/usr/bin/env python
    
    import re
    
    #you'd open a file and read in the tile properties thing
    fakeTileProperties = "<tileproperties>1</tileproperties>\r"
    
    f = open( "file1.tmx", "rU")
    fo = open( "outputfile.tmx", "wc");
    
    #read source file
    s = f.read();
    
    #find what you need
    m = re.search("([\W\w]*)(<tileset firstgid=\"1\"[\W\w]*)(<layer name=\"background\"[\W\w]*)", s )
    
    #write out to source file
    fo.write(m.group(1))
    fo.write(fakeTileProperties)
    fo.write(m.group(3));
    
    f.close();
    fo.close();
    
    print "done!"
    

    The code handles content before the tile set firstgid="1" just in case there is some.

    To use a script like this in Xcode 4 do the following:

    • put your script in a file next to your project file, name it myscript.py
    • use chmod +x myscript.py to make the script file executable.
    • in your Xcode project select the project and target and "Build Phases" tab and then create a new "Run Script" build phase.
    • leave the default shell of /bin/sh
    • put the following into the script field: $(SOURCE_ROOT)/myscript.py

    Then when you do a build you should see the python script get executed. You can do a really simple test python file to test this (I just did):

    #!/usr/bin/env python
    
    print 'hello from python!'
    

    note that the setting in the Run Script setup "Show Environmental variables in build log" is very helpful for getting the environmental variables like SOURCE_ROOT and such to locate your files.

    good luck!