abc.txtという区切りファイルがあります。列名がカンマ(、)で区切られたヘッダー行があります。すべてのデータ行とヘッダー行に使用される行区切り文字は%=$%です(新しい行を表す改行なし)。データ行の列区切り文字は |#@| です。 Unixでデータ行に33列を持たない行を見つけるには?
答え1
Unbuntu 18 では、GNU Awk 4.1.4 を%=$%
レコード区切り文字として使用できません。マクロが入っています。TXR不明瞭な音声働く
33フィールドなしでレコードを印刷する:
$ echo -n 'A,B,C,D%=$%FOO|#@|BAR%=$%X' | \
txr -e '(awk (:set rs #/\%=$\%/ fs ",")
((= nr 1) (set fs #/\|#@\|/) (next))
((/= nf 33) (prn)))'
FOO|#@|BAR
X
TXR Lispの正規表現はであり、#/.../
演算子%
(貪欲ではないバージョン*
)なので、エスケープする必要があります。
強制的に再計算するために、フィールドリストをそれf
自体に割り当てることができます。(set f f)
rec
ofs
$ echo -n 'A,B,C,D%=$%FOO|#@|BAR%=$%X' | \
txr -e '(awk (:set rs #/\%=$\%/ fs ",")
((= nr 1) (set fs #/\|#@\|/) (next))
((/= nf 33) (set f f) (prn)))'
FOO BAR
X
フィールドは[f 0]
、[f 1]
であり、レコード全体は、およびrec
とは異なります。 Awkと同様に、フィールドを強制的に再計算する最も短い方法です。$1
$2
$0
(set f f)
rec
f
$1=$1
GNU Awkで同じように動作できない理由デバッグに戻って...
知っていた:
$ echo -n 'A,B,C,D%=$%FOO|#@|BAR%=$%X' | gawk \
'BEGIN { RS="%=\\$%"; FS = "," }
NR == 1 { FS = "\\|#@\\|" }
NF != 33 { $1=$1; print }'
A B C D
FOO BAR
X
next
ルールが欠落しているため、NR == 1
ヘッダも表示されます。
awkの$
正規表現の文字はエスケープする必要がありますが、RS
それは問題です。もちろん今、私はこれを不正確で混乱させようとしました。
# incorrect escaping of $
$ gawk -v RS='%=\$%' ''
gawk: warning: escape sequence `\$' treated as plain `$'
しかし、ここで私たちがすることは、正規表現として解釈される文字列を割り当てることです。 Gawkは、\$
文字列リテラル構文にエスケープがないと言います。これは正しいです。しかし、私たちにとって必要なのは、ドル記号を正規表現文字でエスケープすることです。これをAwk文字列に入れるには、それをエスケープして\\
から$
正規表現の意味をエスケープする必要があります。