Sedは特定の場所のセットで置き換えられます。

Sedは特定の場所のセットで置き換えられます。

次のサンプル入力ファイルがあります。

Apple   Orange      Gold    Silver Spoon Apple  Orange              Gold    
Apple          
Apple   Orange 
Apple   Orange      
Mango               Gold    Silver Spoon Apple  Orange  

15〜20番目の位置が空白であることを確認し、それを文字列に置き換える必要がありますSilver。また、50〜70位のコンテンツを完全に置き換える必要があります。xxxxxxxxxxxxxxxxxxxxx

答え1

より小さい行を処理する方法に応じて(上記の説明を参照)、sed解決策は次のとおりです。

sed -e '/^.\{14\} \{6\}/s/^\(.\{14\}\) \{6\}/\1Silver/' \
    -e '/^.\{49\}./s/^\(.\{49\}\)\(.\{1,21\}\)\?\(.*\)\?/\1xxxxxxxxxxxxxxxxxxxxx\3/'

そして、よりクリーンでエラーの少ないGNUawkバージョンは次のとおりです。

awk '
  BEGIN { FIELDWIDTHS = "14 6 29 21 999" ; OFS = "" }
  $2 == "      " { $2 = "Silver" }
  $4 != ""       { $4 = "xxxxxxxxxxxxxxxxxxxxx" }
  { print }
'

説明する:

1.) sed:このsedコマンドは、2つの独立した置換で構成されています。最初は「シルバー」ケースを処理し、2番目は「xxx ...」ケースを処理します。交換形態sedは次のとおりです。

/pattern/s/pattern2/replacement/

最初のパターンが一致した場合、対応する置換が実行され、その行の場合、2 番目のパターンが置換式で置き換えられます。詳細はsed一般的に秘密です。

.-どんなキャラクターでも

\{14\}- 前のサブ式を繰り返します(ここでは14回)。

\(expr\)- 代替文字列で等として参照できるサブ式\1\2ここで、実際の数字はn番目の角括弧式として定義されます。

\?– 前のサブ式がオプション部分であることを指定します。

2.) アーク:プログラムはこのセクションを一度実行し、左側のawk条件が真の場合にのみBEGINデータファイルの各行の後続のセクションとその右側のタスクを実行します。{...}

FIELDWIDTHS$i- 各フィールドが(一部のフィールド番号iの場合)として処理できるように、入力行のデータフィールドの幅を指定します。

OFS=""- 空の文字列、出力フィールドに追加の区切り文字を含めないでください。

$2 == " "- 2番目のフィールド(仕様に従ってFIELDWIDTHS)に6つのスペースが含まれている場合は、対応する文字列に置き換えます。

$4 != ""- 4番目のフィールドにデータが含まれている場合は、「xxx ...」文字列に置き換えます。

{ print }- 1 つまたは 2 つの以前のジョブによって変更された、または変更されていない行を表示する現在の行の無条件印刷

答え2

sed 's/^\(.\{14\}\)      /\1Silver/
     s/^\(.\{49\}\).\{20\}/\1xxxxxxxxxxxxxxxxxxxxx/
'    <infile >outfile

はい、私の考えでは。

答え3

Perlを使用して、21文字未満の文字を含む行(最初の置換の場合)と70文字未満の文字を含む行(2番目の置換の場合)を削除する必要があるとします。

< inputfile perl -pe 's/^(.{14}) {6}/$1Silver/; s/^(.{49}).{21}/$1xxxxxxxxxxxxxxxxxxxxx/' > outputfile

21文字未満の文字を含む行(最初の置換の場合)と70文字未満の文字を含む行(2番目の置換の場合)を最初にスペースで埋める必要があると仮定するには、awk+Perlを使用します。

< inputfile awk '{printf "%-70s\n", $0}' | perl -pe 's/^(.{14}) {6}/$1Silver/; s/^(.{49}).{21}/$1xxxxxxxxxxxxxxxxxxxxx/' > outputfile

コマンド#1失敗:

  • < inputfile:コンテンツを「s」inputfileにリダイレクトします。perlstdin
  • -p:Perlにこの行を印刷するように強制します。
  • -e: Perl に引数からプログラムラインを読み込むように強制します。
  • > outputfileperl:コンテンツをstdout次にリダイレクトします。outputfile

コマンド#2分割:

  • < inputfilein awk:コンテンツを 's'inputfileにリダイレクトします。awkstdin
  • {printf "%-70s", $0}:行の文字数が70になるまで、各行にスペースを埋めます。
  • |awkパイプでstdout接続perlstdin
  • -p:Perlにこの行を印刷するように強制します。
  • -e: Perl に引数からプログラムラインを読み込むように強制します。
  • > outputfileperl:コンテンツをstdout次にリダイレクトします。outputfile

代替#1分析:

  • s: 置換を実行するためのアサーション
  • /: 検索モード開始
  • ^: 行の先頭に一致します。
  • (: キャプチャグループを開始
  • .{14}:14回表示される任意の文字と一致
  • ): グループキャプチャの停止
  • {6}:6番登場するキャラクターと一致
  • /:検索モードを停止/交換モードを開始
  • $1:キャプチャされたグループに置き換えられました
  • SilverSilver: 文字列の追加
  • /: 交換モードの停止

代替#2分析:

  • s: 置換を実行するためのアサーション
  • /: 検索モード開始
  • ^: 行の先頭に一致します。
  • (: キャプチャグループを開始
  • .{49}:すべての文字の49項目に一致します。
  • ): グループキャプチャの停止
  • .{21}:21番登場する任意の文字と一致
  • /:検索モードを停止/交換モードを開始
  • $1:キャプチャされたグループに置き換えられました
  • xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: 文字列の追加
  • /: 交換モードの停止

出力例:

:~/tmp$ cat inputfile
Apple   Orange      Gold    Silver Spoon Apple  Orange              Gold    
Apple          
Apple   Orange 
Apple   Orange      
Mango               Gold    Silver Spoon Apple  Orange  
~/tmp$ < inputfile perl -pe 's/^(.{14}) {6}/$1Silver/; s/^(.{49}).{21}/$1xxxxxxxxxxxxxxxxxxxxx/'
Apple   OrangeSilverGold    Silver Spoon Apple  Oxxxxxxxxxxxxxxxxxxxxxld    
Apple          
Apple   Orange 
Apple   OrangeSilver
Mango         SilverGold    Silver Spoon Apple  Orange  
~/tmp$ < inputfile awk '{printf "%-70s\n", $0}' | perl -pe 's/^(.{14}) {6}/$1Silver/; s/^(.{49}).{21}/$1xxxxxxxxxxxxxxxxxxxxx/'
Apple   OrangeSilverGold    Silver Spoon Apple  Oxxxxxxxxxxxxxxxxxxxxxld    
Apple         Silver                             xxxxxxxxxxxxxxxxxxxxx
Apple   OrangeSilver                             xxxxxxxxxxxxxxxxxxxxx
Apple   OrangeSilver                             xxxxxxxxxxxxxxxxxxxxx
Mango         SilverGold    Silver Spoon Apple  Oxxxxxxxxxxxxxxxxxxxxx
~/tmp$

関連情報