別のファイルにコピーできるようにファイルを読み、特定の文字列が最初に表示される部分を検索する必要があります。

別のファイルにコピーできるようにファイルを読み、特定の文字列が最初に表示される部分を検索する必要があります。

次のようにサンプルデータファイルを更新します。

empid;1001
empname;ABC
salary;3000
dept;ABC
age;24
dept;112
JOD;20170101
empid;A2001
salary;5000
dept;XYZ
age;27
JOD;20170303
age;92
empid;1002
empname;MAN
salary;11000
dept;SCI
age;30
dept;Geology
JOD;20180607
empid;1005
empname;NAME
salary;10200d
dept;XYZ
JOD;20161212

すべての属性を検索し、各属性の最初の項目を別のファイルにコピーする必要があります。出力は次のようになります。

empid;1001
empname;ABC
salary;3000
dept;ABC
age;24
JOD;20170101
empid;2001
salary;5000
dept;XYZ
age;27
JOD;20170303
empid;1002
empname;MAN
salary;11000
dept;SCI
age;30
JOD;20180607
empid;1005
empname;NAME
salary;10200
dept;XYZ
JOD;20161212

dept2番目の発生は、各値セットにある場合は考慮してはいけません。

empid,empname,salary,dept,age,JOD.

現在、次のコードを使用しています。

awk -v FS=';' OFS=';'{ 
if ($1 == "empid" || $1 == "empname" || $1 == "salary" || $1 == "dept" || $1 == "age" || $1 == "JOD" ) print $0 }' FILE_NAME > NEW_FILE_NAME.

しかし、2回目の登場deptも同様です。ご案内ください。

ベストアンサー1

Kusalanandaが正確で、各従業員の記録がlineで始まると仮定すると、empid次のawkコマンドが機能します。

awk -F';' '$1=="empid" {delete a} !a[$1]++' input.txt > output.txt

これは、配列変数を使用してa発生した属性名を追跡し、まだ属性名が見つからない場合にのみ現在行を印刷します。属性が見つかるたびに配列がempidリセットされます。

より詳細な説明:

  • $1=="empid" {delete a}a新しいレコードが開始されるたびに配列が削除されます。
  • !a[$1]++awk速記表記では、条件付き1ルールの外側の部分は「この行を印刷します」を意味し、0「印刷しない」を意味します。
  • a[$1]++「発生カウンタ」は、属性名の各値に対して増加し、ここでは「配列インデックス」として扱われます。
  • 評価!a[$1]++最初配列項目の現在の値がゼロかどうか(つまり、属性がまだ見つかっていないかどうか)を確認し、printtrueの場合(否定演算子のおかげで)操作を実行し、カウンタをインクリメントします。それから(これは、Cスタイルのプログラミング言語でプレフィックス/サフィックスの増加がどのように機能するかと同じです。)したがって、そのプロパティがまだ見つからない場合は印刷されますが、それ以降の発生は無視されます。

ノートこのdelete aステートメントは2012 POSIX標準で許可されている構文に従い、上記はGNUとGNUに適用されますが、awkStéphane Chazelasmawknawkこの構文をサポートしない実装について次のように述べました。

delete a

と交換する必要があります

split("",a)

おすすめ記事