
テーブルのリストを含むテキストファイルがあります。各テーブルの列を抽出し、テーブル名とともに別のcsvファイルに作成する必要があります。
はい
describe test_table
+-----------+------------+
| col_name | data_type |
+-----------+------------+
| Name | string |
| Age | string |
+-----------+------------+
次の詳細でcsvファイルを作成する必要があります。
test_table,Name,Age
何か提案してもらえますか?
答え1
すべてのUnixシステムのすべてのシェルでawkを使用してください。
$ cat tst.awk
$1 == "describe" {
out = $2
next
}
/^[+]/ {
mod = (++cnt % 3)
if ( mod == 0 ) {
print out
}
next
}
mod == 2 {
out = out "," $2
}
$ awk -f tst.awk file
test_table,Name,Age
答え2
Perlでこれを行う1つの方法の例は次のとおりです。
$ cat extract-column-names.pl
#!/usr/bin/perl -l
while(<>) {
# Is the current line a "describe" line or are we at the End Of File?
if (m/describe\s+(.*)/i || eof) {
# Do we already a table name and column names?
if ($table && @columns) {
print join(",", $table, @columns);
# clear current @columns array
@columns=();
};
# extract table name
$table = $1;
next;
};
# skip header lines, ruler lines, and empty lines
next if (m/col_name|-\+-|^\s*$/);
# extract column name with regex capture group
if (m/^\|\s+(\S+)\s+\|/) { push @columns, $1 };
}
複数のテーブル記述を含む入力の例:
$ cat table.txt
describe test_table
+-----------+------------+
| col_name | data_type |
+-----------+------------+
| Name | string |
| Age | string |
+-----------+------------+
describe test_table2
+------------+------------+
| col_name | data_type |
+------------+------------+
| FirstName | string |
| MiddleName | string |
| LastName | string |
+------------+------------+
実行例:
$ ./extract-column-names.pl table.txt
test_table,Name,Age
test_table2,FirstName,MiddleName,LastName
ただし、このスクリプトは標準入力(例cat table.txt | ./extract-column-names.pl
:)と複数のファイル名引数(例./extract-column-names.pl table1.txt table2.txt ... tableN.txt
:)も処理できます。
data_type
また、各列を抽出する機能を追加することも難しくありません。これは、別の配列(たとえば)に保存されるか、ハッシュ(キーと値として使用される)を@types
使用するようにスクリプトを変更できます。しかし、ハッシュを使用する場合、ハッシュは本質的に順序がないことを覚えておくことが重要です。したがって、列が表示される順序を覚えるには配列が必要です。col_name
data_type
@columns
シングルラインバージョン:
$ perl -lne 'if (m/describe\s+(.*)/i || eof) {if ($table && @columns) {print join(",", $table, @columns);@columns=()}$table = $1;next};next if (m/col_name|-\+-|^\s*$/);if (m/^\|\s+(\S+)\s+\|/) {push @columns, $1};' table.txt
test_table,Name,Age
test_table2,FirstName,MiddleName,LastName
答え3
テスト環境を準備します。
# Get all the table
mysql -S /var/run/mysqld/mysqld.sock -D mysql -e 'SHOW TABLES;' > all_tables
# Get all the column for each tables
xargs -a all_tables -i -- /bin/sh -c '
printf "describe %s\\n" "$1"
mysql -S /var/run/mysqld/mysqld.sock -D mysql -te "DESC $1"
' _Z_ {} >> tables
以下は抜粋です。ファイルはサンプルデータと同じです。
describe column_stats
+---------------+-----------------------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+-----------------------------------------+------+-----+---------+-------+
| db_name | varchar(64) | NO | PRI | NULL | |
| table_name | varchar(64) | NO | PRI | NULL | |
| column_name | varchar(64) | NO | PRI | NULL | |
| min_value | varbinary(255) | YES | | NULL | |
| max_value | varbinary(255) | YES | | NULL | |
| nulls_ratio | decimal(12,4) | YES | | NULL | |
| avg_length | decimal(12,4) | YES | | NULL | |
| avg_frequency | decimal(12,4) | YES | | NULL | |
| hist_size | tinyint(3) unsigned | YES | | NULL | |
| hist_type | enum('SINGLE_PREC_HB','DOUBLE_PREC_HB') | YES | | NULL | |
| histogram | varbinary(255) | YES | | NULL | |
+---------------+-----------------------------------------+------+-----+---------+-------+
describe columns_priv
+-------------+----------------------------------------------+------+-----+---------------------+-------------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+----------------------------------------------+------+-----+---------------------+-------------------------------+
| Host | char(60) | NO | PRI | | |
| Db | char(64) | NO | PRI | | |
| User | char(80) | NO | PRI | | |
| Table_name | char(64) | NO | PRI | | |
| Column_name | char(64) | NO | PRI | | |
| Timestamp | timestamp | NO | | current_timestamp() | on update current_timestamp() |
| Column_priv | set('Select','Insert','Update','References') | NO | | | |
+-------------+----------------------------------------------+------+-----+---------------------+-------------------------------+
以下を使用して解析しますawk
。
awk -F'|' -v OFS=, '
match($0, /^describe /) {
tbl = substr($0, RSTART+RLENGTH)
c = 3
next
}
/^[+]/ && c < 0 {print tbl}
c-- <= 0 {
gsub(/ */, "", $2)
tbl = tbl OFS $2
}
' tables