識別子を含むレコードを含むファイルがあります。各識別子に複数のレコードがある可能性があります。同じ識別子を持つすべてのレコードを検索し、そのレコード内の特定のパターン(特定の場所のY)を見つけたいです。パターンがある場合は、このメトリックの最初のレコードをそのパターンに更新したいと思います。スクリプトでこれを最良に達成するにはどうすればよいですか? (UnixまたはWindows)。ファイルは識別子でソートされます。
以下は、私が達成したい仕事の例です。
identifier1aaaNbbb
identifier1cccNddd
identifier1eeeYfff
識別子1のレコードの1つの位置14に「Y」がある場合、その「Y」は識別子1のレコードの最初の項目に書き込まれます。
identifier1aaaYbbb
identifier1cccNddd
identifier1eeeYfff
awk
どのツール(、、、grep
)sed
がこの作業に最適なのかわかりません。問題を解決する方法をご存知ですか?
答え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 Y
if
rc=$?
sed -i "/^識別子1/s/\(………….\).\(.*\)/\1Y\2/" my_file_name
-i
ファイルの内部編集を示します。次に始まる一致する行だけを
言います。/^identifier1/
インジケータ1s
検索と置換を意味します。次のスラッシュの後に検索/次のスラッシュに置き換えます。
検索:14番目の文字が必要です。これを行うエレガントな方法がありますsed。説明は他人に任せます。簡単な答えは次のとおりです。
-dot- はすべての文字を意味します。したがって、13点は最初の13文字が一致することを意味します。私たちはそれらをそのまま維持したいので、バケットに保管します。 is it(and) - 括弧を避けるだから:
/\( 13 dots \) . \( dot * \)
行の最初の13文字を取得してバケット#1に保存するとしましょう。点は1つの文字と一致することを意味します。ドットでマークされたアスタリスクは、「0個以上の文字一致」、つまり他のすべてのアイテムをバケット#2に保存することを意味します。
今すぐ置き換える:
/\1Y\2/
行をバケット#1、Y、バケット#2の内容に置き換えることを意味します。
これを整理し、より効率的にする方法があります。私の前にはLinuxボックスがなく、何をすべきか覚えていません。
他の人がいつファブ人々が掲示した内容なので、今頃ご理解いただけるでしょう。