Mam dużo plików XML, ponad 50000 z nich.
W niektórych plikach XML niektóre pliki są zapisywane w ten sposób
<filename>abc.JPEG<^Lilename>
^L
to tylko jedna postać, ale nie mogę znaleźć tego, co ^L
znaczy Google.
Kiedy używam cat
do drukowania zawartości pliku, pokazuje to następująco
<filename>abc.JPEG<
ilename>
W każdym razie, chcę zmienić <filename>abc.JPEG<^Lilename>
na<filename>abc.JPEG</filename>
Znalazłem już polecenie zmiany słowa w wielu plikach, np
find . -exec perl -pi -e 's/[find_word]/[change_word]/g' {} \;
Ale to polecenie nie działa w moim przypadku, ponieważ nie może rozpoznać szukanego słowa, gdy piszę ^L
.
Jak mogę zmienić <filename>abc.JPEG<^Lilename>
na <filename>abc.JPEG</filename>
wiele plików?
<\filename>
zamiast</filename>
w kontekście, który\f
byłby interpretowany jako znak w formularzu. Prawdopodobnie powinieneś wyśledzić źródło tych plików i zwrócić uwagę programisty na problem z ich narzędziem do generowania. W przypadku naprawy plików zaakceptowana odpowiedź jest w porządku.Odpowiedzi:
Control-L (reprezentowany jako
^L
) jest znakiem „form feed”. W ASCII ma wartość dziesiętną 12 (L
jest 12 literą alfabetu) lub wartość szesnastkową 0c:Możesz go zastąpić za pomocą narzędzi takich jak sed, określając szesnastkowy kod ucieczki:
Możesz też komponować
^L
bezpośrednio, używając sekwencji CTRLklawiszy V CTRL+ +LPodane do konkretnego zamiennika
następnie
(
g
modyfikator jest dodawany w przypadku, gdy występuje więcej niż jedna instancja na linię).źródło
find
że zapętliło te 50000 plików XML i automatycznie przetworzyło każdy z nich (i również wykonało kopię zapasową).Jak zauważa Hans-Martin Mosner w komentarzach, wydaje się, że ktoś używał ukośników odwrotnych zamiast ukośników do przodu podczas generowania XML (lub ewentualnie prowadził całą
<filename>
sekcję przez konwerter Unix-na-Windows, który był nadgorliwy o ukośnikach).\f
jest rzadko używaną sekwencją zmiany znaczenia dla znaku w formularzu, znanym również jako U + 0C lub ^ L. Więc jakiś późniejszy etap potoku zastąpił\f
literalnymi znakami U + 0C.Na szczęście U + 0C jest niezwykle rzadką postacią, która prawdopodobnie nie zostanie celowo znaleziona w jakimkolwiek formacie XML. A skoro tylko
\f
będzie produkować ten, w przeciwieństwie do (powiedzmy)\g
lub\k
, uniwersalny find-a-wymienić należy ustalić nie tylko</filename>
, ale również</folder>
,</file>
albo cokolwiek innego, ale zniekształcone.Tak właśnie działa skrypt sed steriderrivera; Chciałbym tylko uczynić to nieco bardziej ogólnym:
Oznacza to „(s) wap we wszystkich przypadkach
\x0c
(to znaczy U + 0C) do/f
, (g) lobalnie”.źródło
\f
to znak kanału informacyjnego w Perlu. Wygląda na to, że te zniekształcone pliki zostały utworzone przez kogoś nowego zarówno w Perlu, jak i XML.Oto poprawka o wiele bardziej precyzyjna - która również spełnia cele PO dotyczące zautomatyzowania aktualizacji wszystkich plików, w przeciwieństwie do akceptowanej odpowiedzi z sed, która będzie działać tylko na jednym pliku na raz, ponieważ nie jest sparowany
find
.\f
można po prostu zastosować sam zamiast kodu szesnastkowegox0c
.Tutaj dodałem
-type f
do tel, aby zwracałfind
tylko zwykłe pliki - w przeciwnym raziefind
powróci.
na listę i wyśle ostrzeżenie, gdy spróbujesz go edytować, chociaż wszystko inne nadal będzie działać.Uczyniłem też wyrażenie regularne łatwiejszym, używając
x
flagi, która ignoruje prawdziwe białe znaki, pozwalając na rozmieszczenie elementów wyrażenia regularnego. Jeśli ci się nie podoba, tutaj jest bez:I w prawdopodobnym przypadku, gdy wszystkie znaki wysuwu formularza są fałszywe i wszystkie powinny zostać zastąpione
/f
, możesz jeszcze bardziej odchylić linijkę:Nie musisz używać ukośników, aby otoczyć elementy polecenia podstawienia wyrażenia regularnego (
s///
) w Perlu. Możesz użyć dowolnego symbolu. Jeśli jednak zdecydujesz się na użycie dowolnego sparowanego symbolu przypominającego nawias klamrowy, musisz użyć ich obu:s[old][new]
na przykład.Ponieważ nie używam ukośników, nie muszę uciekać żadnym ukośnikom.
Jeśli chodzi o
-i.bkp
:perl -pi -e
pozwala edytować w miejscu - ale jeśli potrzebujesz dodatkowego ubezpieczenia na wypadek, gdyby Twój program Perl znalazł i zamienił źle, możesz umieścić rozszerzenie pliku, aby utworzyło kopię oryginalnych plików dla ty. Tutaj wykorzystałem.bkp
.W najnowszych wersjach Perla edycja lokalna została zaktualizowana, aby była bardziej odporna na wypadek poważnych problemów z systemem, takich jak utrata zasilania lub brak miejsca na dysku. Oto autor Perla, brian d foy, na temat ulepszonej edycji na miejscu w najnowszym Perlu.
Należy wziąć pod uwagę przy użyciu Perl dla tego rodzaju zadań, ponieważ jest to bardzo potężne, ale pod oceniane językiem programowania ogólnego przeznaczenia, którego jednym z celów było oryginalne wzornictwo zastąpić
sed
iawk
coś znacznie lepiej.Regex możliwości dopasowywania Perl 5'S i ulepszona składni regex znacznie przekraczają te
sed
,awk
i rzeczywiście każdy inny język programowania oprócz Perl 6, dzięki czemu Perl najbardziej rozsądny wybór zarówno dla prostych, jak i zaawansowanych manipulacji regex.Wyjaśnienie:
sed
będzie również działało OKfind
i możesz również użyćsed -i.bkp
do wykonania kopii zapasowej każdego edytowanego pliku, ale o ile wiem, nie ma dodatkowej odporności w Perlu 5.28 i nowszych. Wykorzystuje również bardziej skomplikowaną i znacznie mniej wydajną tradycyjną składnię wyrażeń regularnych UNIX ®.źródło