列が2つしかないCSVファイルがあります(ただし、場所行)と常にアスタリスク(*)文字で始まり、3つ以上の列にまたがる可能性のある不規則な行があります。 Linuxコマンドラインのみを使用すると、予想される動作は次のとおりです。
- 3つ以上の連続したデータ行が2番目の列の値が等しい場合は、中央の行を削除します。開始線と終了線を維持します。
- アスタリスクで始まる不規則な線の維持
たとえば、次のようなCSVがある場合:
0,Apple
1,Apple
2,Apple
* Checkpoint
* Another checkpoint
3,Apple
4,Apple
5,Box
6,Box
7,Citrus
8,Box
9,Apple
10,Apple
11,Apple
12,Dove
13,Citrus
* Sudden checkpoint, * Leftover checkpoint note 1, * Leftover checkpoint note N
14,Citrus
15,Citrus
16,Citrus
17,Apple
18,Citrus
それでは、次のようになります。
0,Apple
* Checkpoint
* Another checkpoint
4,Apple
5,Box
6,Box
7,Citrus
8,Box
9,Apple
11,Apple
12,Dove
13,Citrus
* Sudden checkpoint, * Leftover checkpoint note 1, * Leftover checkpoint note N
16,Citrus
17,Apple
18,Citrus
上記の例では、1~3行、10行、14~15行が削除されました。
どんな答えでもよろしくお願いします。
乾杯
ベストアンサー1
使用awk
:
BEGIN { FS = "," }
/^[*]/ { print; next }
{
if (NR > 1 && $2 == word) {
tail = $0
++count
} else {
if (count) print tail
word = $2; count = 0
print
}
}
END { if (count) print tail }
スクリプトawk
は、無条件で始まるすべての行を印刷します*
。行がそのような行ではなく、2番目のフィールドの単語が私たちが覚えている単語である場合、そのレコードを変数tail
(同じ単語を含む一連のレコードの最後のレコードと同じ「尾」)に保存します。フィールド)。
2番目のフィールドが次の場合いいえ以前と同じで、tailレコードを印刷します。以前の実行の複数のレコードがある場合は、新しい単語を覚えていて、同じ単語の2番目のフィールドに現在のレコード(新しい実行の1つ以上のレコードの最初のレコード)を印刷します。 )。
提供されたデータをテストし、次のように仮定します。シンプルなCSV(埋め込み区切り文字や改行文字などがないことを意味します):
$ awk -f script file
0,Apple
* Checkpoint
* Another checkpoint
4,Apple
5,Box
6,Box
7,Citrus
8,Box
9,Apple
11,Apple
12,Dove
13,Citrus
* Sudden checkpoint, * Leftover checkpoint note 1, * Leftover checkpoint note N
16,Citrus
17,Apple
18,Citrus
上記と似ていますが、使用ミラー( mlr
)これはCSVをサポートし、複雑な引用符付き文字列を含むCSVレコードを処理できます。
if (is_not_null(@word) && $2 == @word) {
@tail = $*;
false # omit this record for now
} else {
is_not_null(@tail) {
emit @tail # emit the tail record
}
@word = $2; @tail = null;
true # emit this record
}
end { is_not_null(@tail) { emit @tail } }
filter
awk
これは、上記のコードとよく似たロジックを使用して入力データセットのレコードを含めるか省略するMillerサブコマンドの式です。 Millerがこの文字で始まる行に移動するように、コマンドラインでuseを*
使用できます。入力をヘッダーレスCSVとして扱うには、withを--pass-comments-with='*'
使用します。--csv
-N
$ mlr --pass-comments-with='*' --csv -N filter -f script file
0,Apple
* Checkpoint
* Another checkpoint
4,Apple
5,Box
6,Box
7,Citrus
8,Box
9,Apple
11,Apple
12,Dove
13,Citrus
* Sudden checkpoint," * Leftover checkpoint note 1"," * Leftover checkpoint note N"
16,Citrus
17,Apple
18,Citrus