Ubuntuの多くのファイルで^ Lコードを変更するにはどうすればよいですか?


8

XMLファイルはたくさんあり、そのうち50000以上があります。

一部のXMLファイルでは、一部のファイルは次のように記述されています

<filename>abc.JPEG<^Lilename>

^Lは1文字ですが^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

どのように私は変更することができます<filename>abc.JPEG<^Lilename><filename>abc.JPEG</filename>多くのファイルに?


6
どうやら誰かがフォームフィード文字として解釈されるコンテキストの<\filename>代わりに使用したようです。これらのファイルのソースを追跡し、生成ツールの問題を開発者に指摘する必要があります。ファイルを修正するには、受け入れられた答えで十分です。</filename>\f
Hans-Martin Mosner

回答:


17

Control-L(として表されます^L)は「フォームフィード」文字です。ASCIIでは、10進数値12(Lアルファベットの12文字目)または16進数値0cを持ちます。

$ printf 'foo\x0cbar\n' | cat -et
foo^Lbar$

$ printf 'foo\x0cbar\n'
foo
   bar

16進数のエスケープコードを指定して、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修飾子は、1行に複数のインスタンスがある場合に追加されます)。


私の場合、「$ printf '<\ x0cilename \ n' | sed 's / <\ x0c / <\\ f / g'」が機能しません。しかし、あなたの答えによると、「$ find。-exec perl -pi -e 's / <\ x0cilename> / <\ / filename> / g' {} \;」うまくいきます。あなたの答えをありがとう:)
ヤン

@ヤン申し訳ありませんが、私の回答でフォワードスラッシュとバックスラッシュを混同していることに気づきました(今すぐ修正)-それでも、sedバージョンが機能しなかった理由はまだ
わかり

とても良い答えです!findこれらの50000 XMLファイルをループし、それぞれを自動的に処理した(そしてバックアップも作成した)という内容が含まれていると、さらに良いでしょう。
キングスレー

2

Hans-Martin Mosnerがコメントで指摘しているように、誰かがXMLを生成するときにスラッシュの代わりにバックスラッシュを使用したようです(または<filename>、スラッシュに熱心なUnix-to-Windowsコンバーター全体でセクション全体を実行した可能性があります)。\fU + 0Cまたは^ Lとも呼ばれる、フォームフィード文字でほとんど使用されないエスケープシーケンスです。そのため、パイプラインの後のステップで、\fをリテラルU + 0C文字に置き換えました。

幸いなことに、U + 0Cは非常にまれな文字であり、XMLで意図的に検出されることはほとんどありません。\f(たとえば)\gまたはとは対照的に、これだけが生成されるため\k、普遍的な検索と置換は、修正するだけで</filename>なく</folder></file>またはマングルしまった何か。

それが、steeldriverのsedスクリプトです。私はそれを非常に少し一般的にするだけです:

sed 's|\x0c|/f|g'

これは、「(s)wapのすべてのインスタンスを\x0c(つまり、U + 0C)から/f(g)loballyにスワップする」ことを意味します。


2

\fPerlの改ページ文字です。これらの不正なファイルは、PerlとXMLの両方を初めて使用する人によって作成されたようです。

これは、多くのペリエ修正です。これは、sedで受け入れられた回答とは異なり、一度に1つのファイルでしか機能しないため、すべてのファイルの更新を自動化するというOPの目標も満たしていますfind

\f16進コードの代わりに、それ自体を単純に使用できますx0c

find . -type f -exec perl -pi.bkp -e 's [ \f ilename ][ /f ilename ]gx' {} \;

ここで私は-type ftel findに追加してプレーンファイルのみを返すようにしました。それ以外の場合find.リストに戻り、編集しようとすると警告が表示されますが、それ以外はすべて機能します。

また、x実際の空白を無視するフラグを使用して、正規表現を見やすくしました。これにより、正規表現の要素の間隔を空けることができます。これが気に入らない場合は、ここにありません:

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' {} \;

s///Perlでは、正規表現置換コマンドの要素()を囲むためにスラッシュを使用する必要はありません。任意の記号を使用できます。ただし、ブラケットのような記号のペアを使用する場合はs[old][new]、たとえば両方を使用する必要があります。

スラッシュを使用していないので、スラッシュをエスケープする必要はありません。

の場合-i.bkpperl -pi -eインプレースで編集できますが、検索と置換のPerlプログラムが間違っている場合に備えて追加の保険が必要な場合は、ファイル拡張子を付けて、元のファイルのコピーを作成できます。君は。ここでは、.bkp

Perlの最新バージョンでは、システムで停電やディスク容量不足などの深刻な問題が発生した場合に備えて、インプレース編集がより弾力的になるように更新されています。これは、最近のPerlで改善されたインプレース編集に関するPerlの作者brian d foyです。

Perlはこれらの種類のタスクに使用することを検討する必要があります。Perlは非常に強力でありながら評価が低い汎用プログラミング言語であるため、元の設計目標の1つは置換sedおよびawkより良い何かを。

Perl 5の正規表現マッチング機能と改良された正規表現構文はsedawkおよびPerl 6を除く他のすべてのプログラミング言語を Perlは単純なものと高度なregex操作の両方で最も賢明な選択肢となっています。

明確にするために:でも問題sedなく動作し、編集した各ファイルのバックアップを作成するfindこともできますがsed -i.bkp、私が知る限り、Perl 5.28以降の特別な復元力は備えていません。また、従来のUNIX®の正規表現の構文よりも、扱いにくく、はるかに強力ではありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.