以前の作業結果をawkに記録する方法は?

以前の作業結果をawkに記録する方法は?

次の形式のデータを含むファイルがあります。一緒に存在し、予測可能なパターンを持つ必要がある3つの行があります。

dn: uid=N-NAME-02, ou=data01, dc=data02, dc=data03
uidNumber: 3423
sambaSID: S-1-1-11-1111111-111111111-11111111-12342
<blank line>
dn: uid=N-NAME-03, ou=data01, dc=data02, dc=data03
uidNumber: 3245
sambaSID: S-1-1-11-1111111-111111111-11111111-32212

3つのグループの2番目のデータ文字列に基づいていくつかの数学を実行し、計算結果をそのグループの3番目の文字列に入力する必要があります。

dn: uid=NAME02, ou=data01, dc=data02, dc=data03
uidNumber: (3423 + 2 * 100)
sambaSID: S-1-1-11-1111111-111111111-11111111-342500
<blank line>
dn: uid=NAME03, ou=data01, dc=data02, dc=data03
uidNumber: (3245 + 2 * 100)
sambaSID: S-1-1-11-1111111-111111111-11111111-324700

AWKが数学を実行し、結果の値を正しく配置できるため、これを達成するためにAWKを再利用できると思いました。数学部分を直接取り、変数に保存しました。

variable1=`awk -F ': ' '/uidNumber:/ { new = $2 * 2 + 1000; print new }' infile`

その後、同じファイル内の他のコマンドでこの変数を使用して置換を実行できます。

awk -F '-' -v variable2=$variable1 '/pattern of string 3 / { print $1"-"$2"-"$3"-"$4"-"$5"-"$6"-"$7"-"variable2 }'

文字列3データは、ダッシュ「-」で区切られた長い文字列であることに注意する必要があります。最後のダッシュの後に計算された値を配置する必要があります。

これはすべて機能しますが、1つの重要な欠陥があります。ファイルにレコードが1つある場合にのみ機能します。誰かが私にこれを行う方法についてのヒントを与えることができますか?

ベストアンサー1

match()この機能は以下で利用できますawk

$ cat file
somedata45
somedata47
somedata67

somedata53
somedata23
somedata12

awk '
BEGIN { RS = ""; OFS = "\n"; ORS = "\n\n" }
match($2, /[0-9]+/) { value = (substr($2, RSTART, RLENGTH) + 5) * 100 }
match($3, /[0-9]+/) { $3 = substr($2, 1, RSTART - 1) value }1' file
somedata45
somedata47
somedata5200

somedata53
somedata23
somedata2800

レコード区切り記号を空白に設定して、短絡モード(空白行区切り)を有効に有効にしました。各段落の2行目は私たちのものになり$2、3行目は$3などになります。出力フィールド区切り文字を改行文字に設定しました。短絡モードのため、出力レコード区切り文字も2つの改行に設定しました。出力は最後に追加の改行を提供します。

このmatch()関数を使用して数字の始まりを識別します。一致が見つかると、関数は2つの変数を入力し、一致がRSTART開始RLENGTHされた時期と期間を示します。これらの変数を使用して計算を実行し、結果を変数に保存しますvalue。このsubstr機能を使用して数字を見つけます。

同じことを繰り返します$3。今回は、substr数字の先頭を印刷し、数値部分を前の行で計算された値を含む変数に置き換える関数を使用します。

参考にしてください文字列関数詳細については、ユーザーガイドを参照してください。


実際のデータに基づいて更新されました。

実際のデータは実際に仕事をはるかに単純にします。

awk '
/^uidNumber/ { value = $NF } 
 /^sambaSID/ { 
    n = split ($NF, tmp, /-/)
    tmp[n] = ((value + 2)* 100)
    for (i=1; i<=n; i++) { nf = (nf ? nf "-" tmp[i] : tmp[i]) }
    $NF = nf
    nf = ""
}1' file
dn: uid=NAME02, ou=data01, dc=data02, dc=data03
uidNumber: 3423
sambaSID: S-1-1-11-1111111-111111111-11111111-342500

dn: uid=NAME03, ou=data01, dc=data02, dc=data03
uidNumber: 3245
sambaSID: S-1-1-11-1111111-111111111-11111111-324700

uidNumber最後のフィールドを含む行を見つけてキャプチャします。線が表示されたら、sambaSID最後のフィールドを分割し-、最後の要素を新しく計算された値に変更します。次にfor loopa を使用して最後のフィールドを再グループ化します。

おすすめ記事