私のawkスクリプトはでレコードを読み取り、file1
で同じレコードを見つけて、file2
(レコード内の)置換位置をここで定義されたシンボルに置き換えます。しかし、期待どおりに置き換えられない値はほとんどありません。単語の最初のインスタンスのみが置き換えられます。
TYTYTY
入力するT##Y##
TYTYTYGGHG
入力するT##Y##GGHG
LEFT
入力するL##T
LEFT NAME
入力するL##T NAME
予想される出力は次のとおりです。
私のコード -
awk ' FNR==NR
{
if ($0 in word)
next
word[$0]=$0
for (i=1;i<=NF;i++)
{
old=$i
new=""
while (old) {
len=length(old)
new=new substr(old,1,1) substr("##",1,len-1)
old=substr(old,4)
}
id=index(word[$0],$i)
word[$0]=substr(word[$0],1,id-1) new substr(word[$0],id+length($i))
}
next
}
{
for (i in word)
{
regex = "\\<" i "\\>"
gsub(regex, ext[i])
#id=index($0,i)
#while(id>0) {
#$0=substr($0,1,id-1) word[i] substr($0,id+length(word[i]))
#id=index($0,i)
}
}
print
}' records test.html > output.html
$ cat records
LEFT NAME
LEFT NAME 2
LEFT
LEFT 123
TYTYTYGGHG
TYTYTY
AB 8263
AB SCENARIO DEBUG
AB 8263 SCENARIO DEBUG
$cattest.html
<html>
<body>
<hr><br><>span class="table">TabA</span><table>
<tr class="column">
<td>LEFT NAME</td>
<td>LEFT</td>
<td></td>
<td>LEFT NAME 2</td>
<td>LEFT 123</td>
<td>TYTYTYGGHG</td>
<td></td>
<td>TYTYTY</td>
</tr>
<tr class="data">
<td></td>
<td></td>
<td></td>
<td>AB 8263</td>
<td></td>
<td></td>
<td>AB SCENARIO DEBUG</td>
<td>AB 8263 SCENARIO DEBUG</td>
</tr>
</table>
</body>
</html>
必要なアクション -
<html>
<body>
<hr><br><>span class="table">TabA</span><table>
<tr class="column">
<td>L##T N##E</td>
<td>L##T</td>
<td></td>
<td>L##T N##E 2</td>
<td>L##T 1##</td>
<td>T##Y##G##G</td>
<td></td>
<td>T##Y##</td>
</tr>
<tr class="data">
<td></td>
<td></td>
<td></td>
<td>A# 8##3</td>
<td></td>
<td></td>
<td>A# S##N##I# D##U#</td>
<td>A# 8##3 S##N##I# D##U#</td>
</tr>
</table>
</body>
</html>
電流出力 -
<html>
<body>
<hr><br><>span class="table">TabA</span><table>
<tr class="column">
<td>L##T NAME</td>
<td>L##T</td>
<td></td>
<td>L##T NAME 2</td>
<td>L##T 123</td>
<td>T##Y##GGHG</td>
<td></td>
<td>T##Y##</td>
</tr>
<tr class="data">
<td></td>
<td></td>
<td></td>
<td>A# 8##3</td>
<td></td>
<td></td>
<td>A# S##N##I# D##U#</td>
<td>A# 8##3 SCENARIO DEBUG</td>
</tr>
</table>
</body>
</html>
答え1
それでもこれは詐欺ではありません。https://stackoverflow.com/questions/34375020/why-the-output-of-array-using-awk-is-not-in-right-order非常に近い。
要約:awk配列がソートされていません(一般的に言えば)
awkで配列を繰り返すときにfor (i in word)
「インデックス」値(下付き文字またはキーとも呼ばれる)が返される順序は次のとおりです。指定されていない渡す基準;伝統的に、これらの配列はハッシュテーブルとして実装され、ハッシュテーブルが特定のハッシュコードモジュールで特定の値になる順序で繰り返され、競合または再ハッシュ(いわゆる「クローズハッシュ」)で修正できます。 。これは、アイテム/キーが挿入される順序とは異なります。これは一般的に決定的ですが、人間の観点からはランダムに見えるほど複雑です。
したがって、あなたの例では、使用するawkと正確なデータに基づいてループが処理される前にアイテムを処理する可能性が高く、結果として一致を含むfor
行がに変更され、その後ループが処理しようとしない場合に発生します。一致すれば行ではありません。追加の変更が行われます。同様に、一致しない項目が最初に処理され、一致しない項目が最初に処理されます。異なるawkまたは別のfile1データで実行すると異なるシーケンスが生成される可能性があるため、異なる環境で実行すると異なる結果が生じる可能性があります。LEFT
LEFT NAME
LEFT NAME
LEFT
L##T NAME
LEFT NAME
TYTYTY
TYTYTYGGHG
AB 8263
AB 8263 SCENARIO DEBUG
またFNR==NR
(例:file1)ブランチではnew-new substr(old,1,1) substr("##",1,len-1)
必要=
ありません-
。個人的には、対応するサブループを作成する方が自然だと思います。
old=$i; new=""; for(c=1; c<=length(old); c++) new = new (c%3==1? substr(old,c,1): "#")
違いは小さいが。同じ長さの保護されたバージョンではなく、オプションで後にorが10
つ以上の数字で完全に構成されている場合、サブループはfile1のすべての単語を空の文字列に変更し、オプションでドットを知る必要があります。 。+
-
e