1

このAWK スクリプトの処理を複製する必要がありますが、何をしているのかわかりません。このスクリプト の基本的な機能を教えてください。

入力ファイルを受け取り、出力ファイルを作成しますが、どちらのファイルにもアクセスして、それが何をしているかを確認することはできません。入力ファイルの列を区切るパイプ区切り文字と関係があります。

{ 
   if (NR == 1) {
     line = $0
     len = length(line)
       newlen = len
     while ( substr(line,newlen-1,1) == "|" )
       {
         newlen = newlen - 1
       }
     line = substr(line,1,newlen-1)
   }
     else {
     print line
     line = $0
     }
 }
 END{
      len = length(line)
      newlen = len
    while ( substr(line,newlen-1,1) == "|" ) {
      newlen = newlen - 1
    }
    line = substr(line,1,newlen-1)
      print line
}
4

3 に答える 3

3

最初と最後の行のみで後続のすべてのパイプ文字をトリミングしているように見えます。

于 2011-06-06T18:12:16.913 に答える
3

うわー、これを書いた人は誰でもお金を払ったに違いない。

len = length(line)からまでの2 回出現するコード ブロックはline = substr(line,1,newlen-1)、正規表現の置換として単純に (そしてより明確に) 表現できる文字列変換を行っています。|末尾の文字数を計算してline削除しています。行が 以外の文字で終わる場合|、1 文字が削除されます (これは偶然の可能性があります)。これは、単に として実行するgsub(/(\|+|.)$/, "", line)か、またはgsub(/\|+)$/, "", line)final の|ない動作が問題にならない場合に実行できます。

全体の構造については、コードには 3 つの部分があります: 最初の行で行われるif (NR == 1) {…}こと ( 、他の行で行われること ( else {…})、および最終行以降で行われること ( END {…}))。最初の行では、変数lineはに設定されます。$0変換された. 後続の行では, 保存lineされたlineものが出力され, 現在の行に設定される. 最後に最後の行が出力され, 変換される.行を読むとき、それが最後の行かどうかわからないので、それを保存し、前の行を印刷して次に進みます;ENDブロックでは、最後の行に対して別のことを行います.

これが私がそれを書く方法です。データ フローも同様に自明ではありません (ただし、ほとんど工夫されていません) が、少なくとも、乱雑なテキスト変換に溺れているわけではありません。

function cleanup (line) { gsub(/(\|+|.)$/, "", line); return line }
NR != 1 { print prev }
{ prev = (NR == 1 ? cleanup($0) : $0) }
END { print cleanup(prev) }
于 2011-06-06T19:46:37.960 に答える
1

私は間違っているかもしれませんが、一見すると | を除外しているようです。ファイル内の文字。

于 2011-06-06T17:24:37.153 に答える