役割の変更

役割の変更

600以上のファイルで一重引用符を二重引用符で置き換え、二重引用符を一重引用符に置き換える必要があります。私は一日のほとんどをさまざまなトピックについて読むために送信します。私はいくつかの基本的なシェルスクリプトコマンドしか知らず、正規表現に慣れていないので混乱しています。

以下は私が作成した一般的なサンプルファイルです。

   some text KEYWORD_1 table name column = "string" AND column = "string"
    Additional text
          .
          .
          .
   some text KEYWORD_2 text 'text in quote' etc. 

キーワードを使用して2行の引用符を変更したいと思います。キーワードが常に最初の行と最後の行にあることを保証することはできません。キーワードを検索し、その行のすべての引用符のみを変更するには、私の解決策が必要です。

SEDのメタデータを含む、このフォーラムの同様の質問で見つけたいくつかを試しました。このコマンドの使用方法を理解しようとしていますsed -i 's/foo\(.*baz\)/bar\1/' file。トピックによると、このコマンドは「bazが同じ行に従う場合にのみfooをbarに置き換えます」私のキーワードは同じ行の後ろにありませんが、最初は正しく機能しません。

私も試してみましたが、ex -sc 'g/DEL/s/ALF/BRA/g' -cx file何もできませんでした。コマンドラインでは実行できないとします。 600個のファイルをすべて開いたくはありません。

もちろん、一度試した結果、1行でgrep KEYWORD_1 file | sed -i "s/'/\"/g" file
はなくファイル内のすべての引用符が変更されました。

解決策は簡単だと確信しています。私はそれを見ることができません。どうすればいいですか?

要件に応じて、希望の出力は次のとおりです。

some text KEYWORD_1 table name column = 'string' AND column = 'string'
    Additional text
          . 
          .
          .
some text KEYWORD_2 text "text in quote" etc.

答え1

役割の変更

ある文字セットを別の文字セットに変更するのは通常trこのコマンドの操作ですが、特定の行でのみこれを実行するには、次のsedようなコマンドを使用することをお勧めします。ytr

sed -e "/^KEYWORD_1/  y/\"/'/" \
    -e "/^KEYWORD_2/  y/'/\"/" \
    file

ここの各コマンドはsedラインセレクタで始まり、間のパターンに一致するラインのみが機能することを/^KEYWORD/示します。ここのパターンは文字で始まり、その行の先頭にあることを示します。sed/^

行セレクタの後には、文字をから同じ位置にある文字に置き換えるsed代替コマンドが続きます。y/set1/set2/gset1set2

文字交換

"それぞれを同じ行に'、同時にそれぞれを置き換えるには、次のコマンドを1つだけ使用できます'"

sed -e "/^KEYWORD_1\|^KEYWORD_2/  y/\"'/'\"/" file

答え2

'ここで複雑なのは、すべてをに変更した"後、すべてをに変更した場合"にのみ'残るということです'。したがって、最初に'別のものに置き換える必要があります(たとえば、\0入力ファイルには表示されないと安全に想定できるNULL文字())。その後、別のものに変更する必要"'あります"。たとえば、Perlでは次のようになります。

$ perl -pe "if(/KEYWORD/){s/'/\0/g; s/\"/'/g; s/\0/\"/g}" file
KEYWORD_1 table name column = 'string' AND column = 'string'
Additional text
      .
      .
      .
KEYWORD_2 text "text in quote" etc. 

説明する

  • -pe:与えられたスクリプトを適用した後、各入力行を印刷します-e
  • if(/KEYWORD/){something}something:行が一致した場合にのみ実行されますKEYWORD
  • s/foo/bar/gfoo:行のすべての項目をに置き換えますbar。これはg「グローバル」を意味します。これがなければ、各行の最初の項目のみが置き換えられます。

\"スクリプト自体が二重引用符内にあるため、スクリプト内の二重引用符はエスケープ()する必要があります。


コメントで指摘したように、最初にもっと直接的なアプローチを考えなければなりませんでした。

perl -pe "tr/'\"/\"'/ if /^KEYWORD/" file

演算子tr音訳文字のリスト。一般的な形式はですtr/searchlist/replacementlist/。したがって、一致する行でのみすべてを'置き換えます。""'KEYWORD

答え3

少し粗雑ですが、GNU awkを使って動作します。

$ awk -v sq="'" '/KEYWORD/{if ($0~sq){ gsub(sq,"\"")} else if ($0~"\"") gsub(/\"/,sq)};1' input.txt                      
KEYWORD_1 table name column = 'string' AND column = 'string'
Additional text
      .
      .
      .
KEYWORD_2 text "text in quote" etc.

sq変数は一重引用符を表すために使用されます。コードブロック自体に変数を含めるのは、awkでは少し痛いからです。基本的なアイデアは、パターンを検索し、パターンが見つかった場合に何を置き換えるかを決定することです。 Finalは 1awkにこの行を印刷するように指示します。

ファイルに出力するには、シェル>演算子を使用してテキストを一時ファイルにリダイレクトし、コマンドを使用して古いファイルを新しいファイルに置き換えますmv

関連情報