
データベースダンプであり、1行に1つのエントリを含むtxtファイルがあります。構造は次のとおりです。
1500
29/03/2010
18
02
09
47
17
45
28.248
0
0.01
130
12.721
7908
298,809
YES
3.046.550,39
6.500.000,00
17,444,222
1501
30/03/2010
27
54
28
50
22
03
37.223
0
0.00
97
22,466
7379
421.90
NO
20,262,429
25,000,000.01
17,995,281.33
... the third record starts here
データベースには21のフィールドが含まれています。前の行は、このデータベースの2つのレコードダンプを示しています。空の行は、データベースの空のフィールドを表します。
最初のフィールド(F0)は1500、1501...
2番目のフィールド(F1)は、日、月、年の形式の日付です。
フィールドF2、F3、F4、F5、F6、およびF7は6つの整数です。
私にとって必要なのは、このファイルからF0、F2、F3、F4、F5、F6、F7を抽出して各ファイルの行を作成することです。
上記の2つのレコードが与えられた場合、最終ファイルは次のようになります。
1500,18,02,09,47,17,45
1501,27,54,28,50,22,03
私は数マイルに達するbashスクリプトを使用してこれを行い、すべての行で対話する方法などを知っています。しかし、私はUnixが多くのトリック、特にコマンドであることを知っており、sed
これはおそらく単純な1行で行われます。私は新しいことを学ぶのが好きなので、UNIXの修道士たちにどうすればいいのか見てみたいです。
私はOSX Mavericksを使用しています。ありがとうございます。
答え1
使用awk
:
awk '
BEGIN {
fields[1]
fields[3]
fields[4]
fields[5]
fields[6]
fields[7]
last_field=8
}
( NR%21 in fields ) { printf($0",") }
NR%21==last_field' in_file.txt
または、より良い方法は次のとおりです。
awk '
NR%21 ~ /^(1|3|4|5|6|7)$/ { printf($0",") }
NR%21==8' in_file.txt
GNUには、sed
与えられた行の後のn行目に一致する素晴らしい拡張機能があります。これはここで便利です。 OSXでは動作しませんが、楽しみのために次のことを行います。
sed -n '
1~21 { h }
3~21,7~21 { H }
8~21 { H; g; s/\n/,/gp }' in_file
答え2
1つの方法は次のとおりです。
$ perl -000ne '@f=split(/\n/); print join(",",@f[0,2..7]) , "\n"' file.txt
1500,18,02,09,47,17,45
1501,27,54,28,50,22,03
説明する:
-000
perl
:フィールド区切り文字を連続した改行に設定する短絡モードを有効にします\n\n
。これは、各レコードを行として扱うことを意味します。@f=split(/\n/);
:現在の行(レコード)を改行文字で分割して配列として保存します@f
。配列にはレコードのすべてのフィールドが含まれます。これは、配列フラグメントに@f[0,2..8]
フィールド0と2〜8が含まれることを意味します。print join ",",@f[0,2..8] , "\n"'
:配列フラグメントをコンマで連結し、結果の文字列を印刷してから改行文字を印刷します。
答え3
データに常に特定の数の欠落フィールドがある場合(つまりレコード間に2つ以上のハードリターンがある場合)、単に次のことができます。
$ awk -v RS="\\n{2,}" -F"\\n" -v OFS="," '{print $1, $3, $4, $5, $6, $7, $8}' file.txt
1500,18,02,09,47,17,45
1501,27,54,28,50,22,03