Поиск и замена по нескольким строкам с помощью 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 ответа:
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 строка за строкой:
- ищите шаблон для начала;
- на второй строке выводится полезная часть найденной строки;
- затем идет чтение из файла;
- следующая строка содержит метку, так как теперь мы читаем и ищем строку по строка;
- строка, соответствующая найденному и напечатанному образцу конца;
- поскольку нам нужен только первый совпадающий конечный паттерн, в случае успешной замены переходим к концу скрипта;
- Если замена не была выполнена, не было перехода к концу и переходит переход к
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
, поэтому я не смог проверить ее должным образом. Тем не менее, я нутром чувствую, что это должно сработать для вас.