У меня много XML-файлов, около 50000 файлов.
В некоторых XML-файлах некоторые файлы пишутся так ...
<filename>abc.JPEG<^Lilename>
^ L - это всего лишь один символ, но я не могу найти ^ L означает в Google.
Когда я использую cat
, чтобы напечатать этот файл, он выглядит как ...
<filename>abc.JPEG<
ilename>
В любом случае, я хочу изменить <filename>abc.JPEG<^Lilename>
на <filename>abc.JPEG</filename>
Я уже нахожу некоторую команду для изменения слова во многих файлах, например ...
find . -exec perl -pi -e 's/[find_word]/[change_word]/g' {} \;
но эта команда не работает в моем случае, потому что эта команда не может распознать, когда просто набрать в ^ L.
как я могу изменить во многих файлах?
Управление-L (представленный как ^L
) символ "перевода формата". В ASCII это имеет десятичное значение 12 (L
12-я буква алфавита), или шестнадцатеричное число оценивают 0c:
$ printf 'foo\x0cbar\n' | cat -et
foo^Lbar$
$ printf 'foo\x0cbar\n'
foo
bar
Можно заменить его инструменты использования как sed путем определения шестнадцатеричного управляющего кода:
$ printf 'foo\x0cbar\n' | sed 's/\x0c//'
foobar
С другой стороны, сочините ^L
непосредственно использование клавиатуры упорядочивает CTRL+V CTRL+L
sed 's/CTRL+VCTRL+L//'
Для Вашей определенной замены, данной
$ printf '<\x0cilename\n'
<
ilename
затем
$ printf '<\x0cilename\n' | sed 's/<\x0c/<\/f/g'
</filename
( g
модификатор добавляется в случае, если существует больше чем один экземпляр на строку).
Как Hans-Martin Mosner указывает в комментариях, кажется, что кто-то использовал обратные косые черты вместо наклонных черт вправо при генерации XML (или возможно выполнил целое <filename>
разделяют через преобразователь Unix к Windows, который был фанатичен о наклонных чертах). \f
редко используемая escape-последовательность для символа перевода страницы, иначе U+0C или ^L. Так некоторый более поздний шаг конвейера, затем замененного \f
с литеральными символами U+0C.
К счастью, U+0C является чрезвычайно редким символом, которым это вряд ли будет найдено намеренно в любом виде XML. И с тех пор только \f
произвел бы это, в противоположность (говорит) \g
или \k
, универсальное находит и заменяет, должен зафиксировать не только </filename>
но также и </folder>
, </file>
, или что-либо еще это было искажено.
Это - то, что делает sed-сценарий steeldriver; я просто сделал бы его очень немного более общим:
sed 's|\x0c|/f|g'
Это означает" (s) WAP все экземпляры \x0c
(то есть, U+0C) к /f
, (g) lobally".
\f
символ перевода страницы в Perl. Выглядит, как будто эти уродливые файлы были созданы кем-то плохо знакомым с Perl и для XML.
Вот много Perlier, фиксируют - который также удовлетворяет целям OP автоматизации обновления всех файлов, в отличие от принятого ответа с sed, который будет только работать над одним файлом за один раз, поскольку он не соединяется с find
.
\f
может просто использоваться самостоятельно вместо шестнадцатеричного кода x0c
.
find . -type f -exec perl -pi.bkp -e 's [ \f ilename ][ /f ilename ]gx' {} \;
Здесь я добавил -type f
к телефону find
только возвратить простые файлы - иначе find
возвратится .
в списке и триггере предупреждение, когда Вы попытаетесь отредактировать его, хотя все остальное будет все еще работать.
Я также сделал regex более легкое для наблюдения при помощи x
флаг, который игнорирует реальный пробел, позволяя Вам растянуть элементы Вашего regex. Если Вам не нравится это, здесь это без:
find . -type f -exec perl -pi.bkp -e 's[\filename][/filename]g' {} \;
И в вероятном случае, что все символы перевода страницы являются побочными и все должны быть заменены /f
, затем можно сократить остроту еще больше:
find . -type f -exec perl -pi.bkp -e 's[\f][/f]g' {} \;
Вы не должны использовать наклонные черты вправо для окружения regex элементов команды замены (s///
) в Perl. Можно использовать любой символ. Если Вы принимаете решение использовать какой-либо вид парного подобного скобке символа, однако, необходимо использовать их обоих: s[old][new]
например.
Так как я не использую наклонные черты, я не должен выходить ни из каких наклонных черт.
Что касается -i.bkp
: perl -pi -e
позволяет Вам отредактировать оперативный - но если Вы хотите дополнительную страховку в случае, если Вы получили Ваш находимые и заменяемые программу Perl неправильно, можно вставить расширение файла так, чтобы это сделало копию исходных файлов для Вас. Здесь, я использовал .bkp
.
В новых версиях Perl оперативное редактирование было обновлено, чтобы быть более эластичным в случае, если Ваша система переносит серьезную проблему как потери мощности или исчерпывающий дисковое пространство, также. Вот автор Perl brian d foy на улучшенном оперативном редактировании в недавнем Perls.
Необходимо рассмотреть использование Perl для этих видов задач, потому что это - чрезвычайно мощный все же недооцененный язык программирования общего назначения, одна из чей целей первоначального проекта состояли в том, чтобы заменить sed
и awk
с чем-то намного лучше.
Perl 5 regex соответствие возможностям и улучшенному regex синтаксису далеко превышает те sed
, awk
, и действительно любой язык программирования кроме Perl 6, делая Perl самым разумным выбором и для простых и для усовершенствованных regex манипуляций.
Разъясниться: sed
будет работать хорошо с find
также и можно также использовать sed -i.bkp
для создания резервного копирования каждого файла отредактированным но насколько я знаю, это не показывает дополнительную устойчивость в Perl 5.28 и выше. Это также использует более неуклюжий и намного менее мощный традиционный UNIX ® regex синтаксис.