Поиск и замена по нескольким строкам с помощью sed в Xcode Run Script bin/sh


У меня есть файл Cocos2D tmx, который очень похож на xml и включает в себя возврат каретки и пробелы.

Мои требования:

В каждом файле tmx в Resources / maps_sideScrolling/

Найти и все между

<tileset firstgid="1"

И первое появление

<layer name="background"

И заменить содержимым Resources / maps_sideScrolling/tileProperties.txt

Я попробовал следующее, но безрезультатно. Проблема вызвана строкой для поиска имеет несколько линий.

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

Вот пастебин фрагмента tmx, который я хочу отредактировать: http://pastebin.com/wr39zj1r

4 2

4 ответа:

Geek использует python, чтобы делать такие вещи с файлами карт TMX. Просто вариант для рассмотрения.

Что-то вроде этого (но повторяя все файлы в каталоге etc), и сохраните его как файл .sh:

#!/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!"

Код обрабатывает содержимое перед набором плиток firstgid= " 1 " на всякий случай.

Чтобы использовать подобный скрипт в Xcode 4, выполните следующие действия:

  • поместите ваш скрипт в файл рядом с файлом проекта, назовите его myscript.py
  • используйте chmod +x myscript.py для создания сценария исполняемый файл.
  • в вашем проекте Xcode выберите вкладку project and target и "Build Phases", а затем создайте новую фазу сборки" Run Script".
  • оставьте оболочку по умолчанию /bin / sh
  • поместите в поле сценария следующее: $(SOURCE_ROOT)/myscript.py

Затем, когда вы делаете сборку, вы должны видеть, как выполняется скрипт python. Вы можете сделать очень простой тестовый файл python, чтобы проверить это (я только что сделал):

#!/usr/bin/env python

print 'hello from python!'

Обратите внимание, что настройка В программе запуска скрипта setup " Show Переменные среды в журнале сборки " очень полезно для получения переменных среды, таких как SOURCE_ROOT и таких, чтобы найти ваши файлы.

Удачи!

#!/usr/bin/env bash

sed -rni '/<tileset\s+firstgid="1"/ {
s/(\s*<tileset\s+firstgid="1").*/\1/p
r /home/username/ololofile
:loop
n
s/.*<layer name="background".*/&/p
t
b loop
}' ~/files/to/replace/*

Sed с параметром -n не будет выводить ничего, пока не будет принудительно выполнена печать (p) или не произойдет считывание файла.

Внезапно возникли ошибки, когда я попытался запустить скрипт с комментариями, поэтому удалил свой пост, но потом понял, что пробелы между именем файла для чтения с помощью команды r и комментарием рассматриваются как продолжение имени файла, поэтому я удалил комментарии и теперь буду описывать команды скрипта для sed строка за строкой:

]}
  1. ищите шаблон для начала;
  2. на второй строке выводится полезная часть найденной строки;
  3. затем идет чтение из файла;
  4. следующая строка содержит метку, так как теперь мы читаем и ищем строку по строка;
  5. строка, соответствующая найденному и напечатанному образцу конца;
  6. поскольку нам нужен только первый совпадающий конечный паттерн, в случае успешной замены переходим к концу скрипта;
  7. Если замена не была выполнена, не было перехода к концу и переходит переход к loop метка, в которой новая строка попытается загрузиться в пространство шаблона.
$ cat file1
abc
def
ghi

$ cat file2
pre
stuff
<tileset firstgid="1"
foo
bar
<layer name="background"
post
stuff

$ awk '
   NR==FNR { s=s ORS $0; next }
   /<tileset firstgid="1"/    { print $0 s; f=1 }
   /<layer name="background"/ { f=0 }
   !f
' file1 file2
pre
stuff
<tileset firstgid="1"
abc
def
ghi
<layer name="background"
post
stuff

Обратите внимание, что вышеизложенное заменяет foo\nbar в файле file2 содержимым файла file1 на основе разделителей, которые вы хотели. Если вы хотите удалить разделяющие линии тоже, это тривиальная настройка.

Вот один из способов использования sed. Бегите, как:

sed -f script.sed Resources/maps_sideScrolling/*.tmx

Содержание script.sed:

/<tileset firstgid="1"/ {

    s/\(<tileset firstgid="1"\).*/\1/

    r Resources/maps_sideScrolling/tileProperties.txt

    p

    :a
    N
    s/.*\(<layer name="background".*\)/\1/
    t
    ba
}
Пожалуйста, дайте мне знать, как это происходит. На данный момент у меня нет доступа к машине с BSD sed, поэтому я не смог проверить ее должным образом. Тем не менее, я нутром чувствую, что это должно сработать для вас.