人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

シェル・コマンドラインにおける処理に関して相談です。
SQL ServerのBULK INSERTの前処理なのですが、
以下のような行によってカラム数の差があるデータがあります。

カラム数が足りない場合に足りないカラムを空白で埋めたいのですが、
シェルやsedなどで対応できるコードを教えて下さい


2012-12-01 00:37:56AAAJP13
2012-12-01 01:37:56AAAJP15
2012-12-01 02:37:56BBB
2012-12-01 03:37:56AAACN
2012-12-01 04:37:56DDDJP13

●質問者: まさきん
●カテゴリ:コンピュータ インターネット
○ 状態 :終了
└ 回答数 : 2/2件

▽最新の回答へ

1 ● a-kuma3
●170ポイント ベストアンサー

SQL Server ってありますが、unix 系とかでも良いんでしょうか。

質問で提示した例が、一番長い行が 29文字なので、一行が 29桁になるように末尾に空白を埋めます。
入力が input.txt で、出力を output.txt とします。

まず、sed の例。

sed -e 's/$/ /' -e 's/^\(.............................\).*/\1/' input.txt > output.txt

29個の空白やピリオドを書くのが、うっとおしいですかね。
# vi 使えば、29i とかで数は合わせられますが。


awk だと、こんな感じ。

#! /usr/bin/sh
awk '
BEGIN { PAD = " " } # 29個の空白
{
 print substr($0 PAD, 0, 29)
}
' input.txt > output.txt

awk スクリプトの内容をファイルに書いておいて、-f オプションで指定しても同じです。




タブ区切りだってことで、全面的に改定。

#! /usr/bin/sh
awk '
BEGIN {
 FS = "\t"
 OFS = "\t"
}
NF == 1 { print $0 "\t \t \t " }
NF == 2 { print $0 "\t \t " }
NF == 3 { print $0 "\t " }
NF == 4 { print }
' input.txt > output.txt

ちょっとカッコ悪い?

カラム数を、定数で持ってみたパターン。

#! /usr/bin/sh
awk '
BEGIN {
 FS = "\t"
 OFS = "\t"
 REC_N = 4 # カラム数
}
{
 printf "%s", $0
 n = REC_N - NF
 for (i = 0 ; i < n ; ++i) {
 printf "\t "
 }
 printf "\n"
}
' input.txt > output.txt

4カラムにしているのは、日付と時刻の間はタブではなくて、スペースだろう、という想像からです。


a-kuma3さんのコメント
タブ区切りだってことで、書き直してみました。

まさきんさんのコメント
ありがとうございます。 上記をシェルにして動かすことでmacでは正しく動いたのですが、 cygwinではコードを変える必要があるらしく、以下で動きました。 #! /usr/bin/sh INPUT_FILE=20121201_ggp_evt.data OUTPUT_FILE=20121201_ggp_evt.data2 awk -c ' BEGIN { FS = "?t"# TAB chara fow win platform OFS = "?t" REC_N = 15 # column number } { printf "%s", $0 n = REC_N - NF for (i = 0 ; i < n ; ++i) { printf "\t "# TAB chara for linux platform } printf "\n"# Enter chara for linux } ' ${INPUT_FILE} > ${OUTPUT_FILE}

a-kuma3さんのコメント
-c って、何だろう... ともあれ、期待通りの処理ができて、よかったです。

まさきんさんのコメント
-cはコンパチブルで古いawkと言う意味です。 cygwinだとawkではなくて、拡張されているgawkなので、一応つけてみました

a-kuma3さんのコメント
http://linux.die.net/man/1/gawk --compat と同義なわけですね。 でも、手持ちの gawk じゃ、通らないなあ。 亜種があっても不思議ではないですが。

質問者から

サーバーはSQLですが、cygwinの上、各種ツールはインストール済みです(sed/awk/pyhton/Perlなど)。

また、ファイルはTAB区切りのファイルで、
カラムが足りない行はTABで埋めていく必要があります。


2 ● oil999
●130ポイント

まず確認ですが、

2012-12-01 00:37:56 AAA JP 13 →5つのカラムがある
2012-12-01 02:37:56 BBB →3つのカラムしかない

という状況で、すべての行を5つのカラムに統一したいというご質問ですね。

変換前のデータを "hoge.txt" というファイル名で保存してください。
Windowsであれば、gawk を使って以下のようにします。
http://www.vector.co.jp/soft/win95/util/se376460.html

カラム区切りをカンマにしています。

gawk "{ for (i=1; i<5; i++) { printf(\"%s,\",$i); } print $5; }" hoge.txt

oil999さんのコメント
タブ区切りであれば、以下のようにしてください。 足りないカラムはタブで埋めます。 >|| gawk "{ for (i=1; i<5; i++) { printf(\"%s\t\",$i); } print $5; }" hoge.txt > out.txt ||<

まさきんさんのコメント
ありがとうございます。 こちらは試していないですがcygwinだと\tなどを¥tなどに変える必要があるかもしれません。 感謝です!
関連質問

●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ