
私文書一部の欠落データポイントの値があり、欠落している値はと表示されます****
。 10未満の値を持つ7つの連続した列を持つ行を選択する必要があります。私が走るときスクリプト****
また、連続列に対応する行を提供します。
****
すべてをより高い値に置き換えることで、簡単に問題を解決できます。しかし、入力ファイルを変更したくありません。私のスクリプトが****
数字(より大きい)として扱うように何かをしたいと思います10 i.e. str=****=100
。どうすればいいですか?
入力例consecutive7pointDown10.input
-
2 3 4 5 6 7 8 0 12 14 23
2 3 4 12 6 7 8 0 1 2 23
**** **** **** **** **** **** **** 8 **** **** 12
私のスクリプトの結果consecutive7pointDown10.output
-
2 3 4 5 6 7 8 0 12 14 23
**** **** **** **** **** **** **** 8 **** **** 12
ただし、予想出力
2 3 4 5 6 7 8 0 12 14 23
私のスクリプトconsecutive7pointDown10
は次のとおりです -
#!/bin/bash
########################################################################################################################
# This script results rows having at most 10°C in consecutive at most 7 points.
# input = scriptname.input
# output = scriptname.output
########################################################################################################################
input=`basename "$0"`.input
output=`basename "$0"`.output
awk '{
for(i=4;i<=34-6;i++)
{
if($i<=10 && $(i+1)<=10 && $(i+2)<=10 && $(i+3)<=10 && $(i+4)<=10 && $(i+5)<=10 && $(i+6)<=10)
{
print
next
}
}
}' $input > $output
答え1
awk '/(\<[0-9]\s+){7}/{print}' input.txt
または
sed -rn '/(\b[0-9]\s{1,}){7}/p' input.txt
仕事をします。
awkの説明(sedのロジックは同じ):
/(\<[0-9]\s+){7}/{print}
- パターンを含む行を印刷します。\<
- 単語の境界と一致します。つまり、右側の文字が「単語」文字で、左側の文字が「非単語」文字の場合は一致します。[0-9]\s+
0
- に1桁の数字9
、その後に1つ以上のスペースが続きます。(\<[0-9]\s+){7}
-\<[0-9]\s+
パターンが7回繰り返されると一致します。
入力する
2 3 4 5 6 7 8 0 12 14 23
2 3 4 12 6 7 8 0 1 2 23
**** **** **** **** **** **** **** 8 **** **** 12
出力
2 3 4 5 6 7 8 0 12 14 23
編集する:
精度が1の浮動小数点数(9.2、8.1、7.5など)の場合。
awk '/(\<[0-9]\.[0-9](\s+|$)){7}/{print}' input.txt
答え2
awk
すべての条件が満たされた場合に増加するか、逆の場合にリセットされるフラグを使用すると、連続した7つの列を繰り返しチェックすることを回避できます。
awk '{c=0; split($0,arr,/ +/);
for(x in arr) if(arr[x]<10 && arr[x]>=0) {
if(++c==7){ print $0; next } }else{c=0} }' infile
ここではawkの分割機能« split(string, array [, fieldsep [, seps ] ])
»行($0
行全体を表す)をawk
1つ以上のスペースで区切られた名前付き配列に分割します。arr
次に配列要素を繰り返し、その値が10から0の間であることを確認してからcallというフラグを増やしc
、7に達すると行を印刷します(7つの連続要素(列)が条件を満たすことを意味します)。フラグは0に設定されます。
または、行を配列に分割せずに同じ方法で実行します。
awk '{c=0; for(i=1;i<=NF;i++) if($i<10 && $i>=0) {
if(++c==7){ print $0; next } }else{c=0} }' infile
4列から最後までフィルタリングするには、次のものが必要です。NF
で始まる各行のフィールド/列数を示しますawk
。
$ time awk '{c=0; for(i=4;i<=NF;i++) if($i<10 && $i>=0) {
if(++c==7) {print $0; next} }else{c=0} }' infile
real 0m0.317s
user 0m0.156s
sys 0m0.172s
または、正規表現モードで再適用されます。オリジナルファイル浮動小数点のみが含まれている場合(フラグで使用する場合)よりもgrep
効率的で約6倍速い次のコマンドを使用できます。awk
-P
Grep -E、Sed -E - "[x]{1,9999}"を使用するとパフォーマンスが低下しますが、なぜですか?)、しかしawk
範囲を変更することができますので、ソリューションの柔軟性が与えられた場合は、+ 2桁の整数/浮動/混合の場合に機能します。
$ time grep -P '([^\d]\d\.\d[^\d]){7}' infile
real 0m0.060s
user 0m0.016s
sys 0m0.031s
または他の方法で:
$ time grep -P '(\s+\d\.\d\s+){7}' infile
real 0m0.057s
user 0m0.000s
sys 0m0.031s
grep
またはsed
以下との互換性awk
:
$ time grep -E '([^0-9][0-9]\.[0-9][^0-9]){7}' infile
real 0m0.419s
user 0m0.375s
sys 0m0.063s
$ time sed -En '/([^0-9][0-9]\.[0-9][^0-9]){7}/p' infile
real 0m0.367s
user 0m0.172s
sys 0m0.203s
$ time awk '/([^0-9][0-9]\.[0-9][^0-9]){7}/' infile
real 0m0.361s
user 0m0.219s
sys 0m0.172s