パターンを検索し、最初のパターン発生でレコードを更新します。

パターンを検索し、最初のパターン発生でレコードを更新します。

識別子を含むレコードを含むファイルがあります。各識別子に複数のレコードがある可能性があります。同じ識別子を持つすべてのレコードを検索し、そのレコード内の特定のパターン(特定の場所のY)を見つけたいです。パターンがある場合は、このメトリックの最初のレコードをそのパターンに更新したいと思います。スクリプトでこれを最良に達成するにはどうすればよいですか? (UnixまたはWindows)。ファイルは識別子でソートされます。
以下は、私が達成したい仕事の例です。

identifier1aaaNbbb  
identifier1cccNddd  
identifier1eeeYfff

識別子1のレコードの1つの位置14に「Y」がある場合、その「Y」は識別子1のレコードの最初の項目に書き込まれます。

identifier1aaaYbbb  
identifier1cccNddd  
identifier1eeeYfff

awkどのツール(、、、grepsedがこの作業に最適なのかわかりません。問題を解決する方法をご存知ですか?

答え1

入力ファイルを2回使用しawkて読み込み処理します。

Yこれはあなたの識別子の長さが11文字で、行の15番目の文字を探していると仮定します(あなたの例のように)。識別子の長さが常に11文字でない場合は、スクリプトの最初の行を変更する必要があります。

最初のパス:各識別子の最初のレコードを配列に保存し、Yレコードが見つかったらこの配列要素を変更します。

2番目のステップ:各識別子の最初のレコード行を保存され、変更された配列値に置き換えて、その行を印刷します。

awk '{
  ident=substr($0,0,11)  # get identifier
  if (NR==FNR){          # first pass
    if (!(ident in a)){  # if identifier is not present in array
      a[ident]=$0        # save current line in array
    }
    if (substr($0,15,1) == "Y"){  # if `Y` is found in current line
                                  # replace character with `Y` in array value
      a[ident]=substr(a[ident],0,14)"Y"substr(a[ident],16)
    }
  }
  else {               # second pass
    if (ident in a){   # if identifier is present in array
      $0=a[ident]      # replace current line
      delete a[ident]  # delete array element
    }
    print              # print current line
  }
}' file file

答え2

いいえエレガント。参考のためにのみ使用してください。

まず、すべてのidentifier1レコードを識別します
。 command1:grep '^identifier1' my_file_name
これで印刷されます。ただ選択したラベルがある行です。後で別の識別子を持つレコードを見つけることができます。

これらの履歴があれば検索できます。ただ列 14、cut コマンドの使用:
command2:_command1_ | cut -c14
明確にするために、コマンドに略称表記法を使用しました。彼らはあなたに意味があることを願っています。 command2 14番目の文字(「char」の場合)
のみを印刷するには、cutコマンドを使用します。その後、この出力で「Y」を見つけることができます。 command3: -q は「静か」を意味し、何も出力しません。注:一部の人はrcが必要ないと言います。 $? を見るだけです。あなたの電話。この時点で$ rc(または$?)が0の場合、grepは少なくとも1つの大文字のYを探します。それ以外の場合は1(エラーを示す他の数字かもしれません)です。次のようにコーディングしてみましょう。注:間にコマンドを入力して$?を使用する必要がある場合は、$?を使用してください。 N のすべてのインジケータを Y に変更するには、次の sed コマンドを実行できます。 -c


_command2_ | grep -q Y
rc=$?


if [ $rc -ne 0 ] then echo "No Ys found" exit fi
grep -q Yifrc=$?

sed -i "/^識別子1/s/\(………….\).\(.*\)/\1Y\2/" my_file_name

-iファイルの内部編集を示します。次に始まる一致する行だけを
言います。/^identifier1/インジケータ1
s検索と置換を意味します。次のスラッシュの後に検索/次のスラッシュに置き換えます。
検索:14番目の文字が必要です。これを行うエレガントな方法がありますsed。説明は他人に任せます。簡単な答えは次のとおりです。
-dot- はすべての文字を意味します。したがって、13点は最初の13文字が一致することを意味します。私たちはそれらをそのまま維持したいので、バケットに保管します。 is it(and) - 括弧を避けるだから:
/\( 13 dots \) . \( dot * \)行の最初の13文字を取得してバケット#1に保存するとしましょう。点は1つの文字と一致することを意味します。ドットでマークされたアスタリスクは、「0個以上の文字一致」、つまり他のすべてのアイテムをバケット#2に保存することを意味します。

今すぐ置き換える:
/\1Y\2/行をバケット#1、Y、バケット#2の内容に置き換えることを意味します。

これを整理し、より効率的にする方法があります。私の前にはLinuxボックスがなく、何をすべきか覚えていません。
他の人がいつファブ人々が掲示した内容なので、今頃ご理解いただけるでしょう。

関連情報