アッ

アッ

同じ長さの2つのデータ行があるとします。

abcdb#lae#blabl#a
abc~bola~xblabl~a

#最初の行の文字(最初の行には1つ以上の#を含めることができます)を削除し、次の行の同じ場所にある文字を削除する必要があります。

abcdblaeblabla
abc~bla~blabla

私はこれを試しましたが、sed '/#/{n;s/~//g}'私が望むよりも多くの文字を削除します。

ベストアンサー1

アッ

これらの方法は各行のペア(1と2、3と4など)に対して繰り返され、各ペアの#最初の行にある文字数だけ処理し、各ペアの2行が同じであると仮定します。長さ。

GNU awk(Linux)およびBSD awk(Mac)と互換性があります。


部分文字列を使用します。

awk '{ a=$0 ; gsub(/#/,"",$0) ; print $0 ; getline ; for (n=1;n<=length(a);n++) if ( substr(a,n,1) != "#" ) printf "%s",substr($0,n,1) ; printf "%s",RS }' file.txt

より狭い画面に合わせて再フォーマットされた同じコード:

awk '{
  a=$0 ;
  gsub(/#/,"",$0) ;
  print $0 ;
  getline ;
  for (n=1;n<=length(a);n++)
    if ( substr(a,n,1) != "#" )
      printf "%s",substr($0,n,1) ;
  printf "%s",RS
  }' file.txt
  • a=$0
    最初の行のコピーを保存します。
  • gsub(/#/,"",$0) ; print $0
    #コピーではなく、最初の行のすべての項目を削除し、変更された最初の行を印刷します。
  • getline
    次の行に移動します。
  • for (n=1;n<=length(a);n++)
    コピー 最初の行の各文字を段階的に実行します。
    • if ( substr(a,n,1) != "#" )
      この単一文字のサブストリングではない場合#...
      • printf "%s",substr($0,n,1)
        ...その後、2行目の対応する位置に文字を印刷します。
  • printf "%s",RS
    2行目を改行文字で終了します。

配列を使用して下さい:

awk '{ c=d="" ; elements=split($0,a,"") ; getline ; split($0,b,"") ; for (n=1;n<=elements;n++) if (a[n]!="#") { c = c a[n] ; d = d b[n] } ; print c ; print d }' file.txt

より狭い画面のための再フォーマット:

awk '{
  c=d="" ;
  elements=split($0,a,"") ;
  getline ;
  split($0,b,"") ;
  for (n=1;n<=elements;n++)
    if (a[n]!="#")
      { c = c a[n] ; d = d b[n] } ;
  print c ;
  print d
  }' file.txt
  • c=d=""
    2つの空の文字列を初期化します。これは入力2行の修正版になります。入力ライン数が2本を超える場合は、この手順が必要です。
  • elements=split($0,a,"")
    入力の最初の行を配列要素ごとに1文字ずつ配列に変換します。配列要素の数を変数として保存しますelements
  • getline
    次の行に移動します。
  • split($0,b,"")
    入力の2行目を配列要素ごとに1文字ずつ含む配列に変換します。
  • for (n=1;n<=elements;n++)
    配列の最初の行にある各要素を段階的に実行します。
    • if (a[n]!="#")
      この単一文字配列要素がない場合#...
      • { c = c a[n] ; d = d b[n] }
        ...その後、2行ごとに文字を配置しますn
  • print c ; print d
    この2行の新しいバージョンを印刷してください。

警告する:Mac(BSD)バージョンのawkは、配列要素を数値順に自動処理しません。これは最初に私に素晴らしい結果を与えました。

「for(indx in array)」ループが配列を巡回する順序は、POSIX awkでは定義されておらず、実装ごとに異なります。 gawkを使用すると、PROCINFO ["sorted_in"]に事前定義された特別な値を割り当てて順序を制御できます。

GNU Awkユーザーガイド

要素はGNU awkのように1,2,3,...作成されてもまだ番号が付けられていますが、BSD awkが使用されている場合は必ずしもその順序で表示されるわけではありません。したがって、無効な文字が表示されます。splitfor (n in array)

この問題を解決するには、たとえば、配列を作成するときに配列の長さ(要素数)を保存し、ここで行ったように要素に対してelements=split($0,a,"")反復for (n=1;n<=elements;n++)を使用できます。


入力例(file.txt):

abcdb#lae#blabl#a
abc~bola~xblabl~a
#alpha#beta#gamma#delta#epsilon#
abcdefghijklmnopqrstuvwxyzabcdef

出力例:

abcdblaeblabla
abc~bla~blabla
alphabetagammadeltaepsilon
bcdefhijkmnopqstuvwyzabcde

おすすめ記事