
ファイルが次のパターンに従うことを確認したいと思います。
... ... ... foo ... foo_KO ... ...
... bar ... ... ... ... bar_KO ...
ファイルが非常に長いので、つまり、次の規則を保証したいと思いますsed
。
([az] *)_KOが一致するたびに、同じ行に\ 1の値を持つ別のフィールドがあります。
私は十分に明確であることを願っています。
私はkshを使用するSolaris 10を使用しています。
例:
入力する
... ... ... foo ... foo_KO ... ...
... bar ... ... ... ... bar_KO ...
出力
valid
入力する
... ... ... foo ... foo_KO ... ...
... bar ... ... ... ... bar_KO ...
... fubar_KO ... ... ... ... ...
出力
invalid line 3
または
unmatched pattern fubar_KO
答え1
これにより、誤った行の行番号が印刷されます。
sed -n '/\([a-z]\+\).*\1_KO/b;/\([a-z]\+\)_KO.*\1/b;=' input_file
しかし、1行に複数の「_KO」を処理しません。
これは、より安定して移植性に優れています。
awk '{for(i=1;i<=NF;i++)if((s=$i)~/^([a-z]+)_KO/){sub(/_KO$/,"",s);o=0;for(j=1;j<=NF;j++)if($j==s)o=1;if(!o)printf"line %d unmatched %s\n",NR,s}}' input_file
これはより厳しく、効率的で、複数のモードをサポートしますが、順序によってはロケールが成功に影響を与える可能性があります。
ruby -nae '$F.sort!.select!{|v|v=~/^[a-z]+(_KO)?$/};$F.each_with_index{|v,k|puts"line #{$.} unmatched #{v}"if v[/^([a-z]+)_KO$/]and$F[k-1]!=$1}' input_file
基本的には上記と同じ解決策ですが、あまりawk
冗長ではないようですperl
。
perl -nae 'for$k(grep/^[a-z]+_KO$/,@F){print"line $. unmatched $k\n"unless grep{$_ eq substr$k,0,-3}@F}' input_file
答え2
神秘的なPerl:
perl -ne '/(\w+)_KO\b/ && !/\b$1(?!_KO)\b/ && print "invalid line $.: missing $1\n"' filename
/(\w+)_KO\b/
「_KO」という単語を見つけて、KO以外の部分を変数にキャプチャします。$1
!/\b$1(?!_KO)\b/
_KO(単語の境界)なしで「スタンドアロン」という単語がない場合は\b
trueです。
両方の条件が true の場合、エラーメッセージを出力します。
ファイルが「有効」であることを確認するには、次のようにします。
output=$(perl -ne '/(\w+)_KO\b/ && !/\b$1(?!_KO)\b/ && print "invalid line $.: missing $!\n"' filename)
[ -z "$output" ] && echo valid
または
perl -ne '
BEGIN {$count = 0}
if (/(\w+)_KO\b/ && !/\b$1(?!_KO)\b/) {print "invalid line $.: missing $!\n"; $count++}
END {$count == 0 && print "valid\n"}
' filename