質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
bash

bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

AWK

AWKは、UNIX 上で開発されたプログラミング言語で、CSVファイルなどのテキストファイルの処理を目的にデザインされています。

Q&A

解決済

3回答

23008閲覧

Linuxで日本語が混ざったファイルを固定長で切り出したい

tpse

総合スコア11

bash

bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

AWK

AWKは、UNIX 上で開発されたプログラミング言語で、CSVファイルなどのテキストファイルの処理を目的にデザインされています。

0グッド

0クリップ

投稿2017/03/27 10:26

お世話になります。
初めて投稿するので、書き方が間違っていたり表現が不順分かも知れませんが、よろしくお願い致します。

###前提・実現したいこと
Linux環境(UTF-8)で、日本語と半角英数字の混在したSQLスプールファイルから、固定長で文字列を抽出したい。

###発生している問題・エラーメッセージ
日本語がUTF-8では3バイトで扱われるのか(?)、スプールファイルの行によってバイト数が違うため、cutやfoldでは固定長で切り出せず、awkのprintfで整形しても若干ずれてしまうようです。

###該当のソースコード
(スプールファイル:sample.spool)※テキストエディタに貼って頂くと固定長と分かります

I173400 材料消費連携 高機能 B1A SR 材料消費連携 17/03/26 01:37:28 01734 08219
I124800 AB:取引先転送 AB:SYSTEM B4A MREAL AB:取引先転送 受信 17/03/26 18:11:18 01248 03916
I125400 AB:工場転送 AB:SYSTEM B4A MREAL AB:工場転送 送信 17/03/26 18:11:18 01254 03928

###試したこと

cut -b -120 sample.spool

I173400 材料消費連携 高機能 B
I124800 AB:取引先転送 AB:SYSTEM B4A
I125400 AB:工場転送 AB:SYSTEM B4A M

fold -b120 sample.spool|grep ^I

I173400 材料消費連携 高機能 B
I124800 AB:
I125400 AB:工場転送

LANG=C cut -b -120 sample.spool

I173400 材料消費連携 高機能 B
I124800 AB:取引先転送 AB:SYSTEM B4A
I125400 AB:工場転送 AB:SYSTEM B4A M

LANG=C fold -b120 sample.spool|grep ^I

I173400 材料消費連携 高機能 B
I124800 AB:取引先転送 AB:SYSTEM B4A
I125400 AB:工場転送 AB:SYSTEM B4A M

LANG=C awk '{printf("%7s %-50s %-50s %3s\n",$1,$2,$3,$4)}' sample.spool

I173400 材料消費連携 高機能 B1A
I124800 AB:取引先転送 AB:SYSTEM B4A
I125400 AB:工場転送 AB:SYSTEM B4A

お手数をお掛けしますが、ご教授いただければ幸いです。
よろしくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

日本語がUTF-8では3バイトで扱われるのか

いえ、2バイトのこともありますし3バイトのこともそれ以上のこともあります。

cutの-bオプションで指定する位置は「バイト位置」ですが上記のようにUTF-8では文字数あるいは文字の見かけの表示幅とバイト数は合致しません。-cオプションで「文字位置」を指定することもできますが、それもうまくいきません。なぜならこのファイルの形式はバイト数としても文字数としても「固定長ではないから」です。固定なのは「見た目の文字幅」だけであり、これはどちらかといえば可変長レコードと捉えたほうがよいでしょう。

ところで日本語を含むデータの場合、見た目の幅がバイト数に(ほぼ?)合致するという特殊な状況があります。それはShift-JISを用いた場合です。それを利用すると、切り出すときだけShift-JISとして扱うという手が使えます。

iconv -f UTF-8 -t SHIFT-JIS input | cut -b ... | iconv -f SHIFT-JIS -t UTF-8 >output

ただ注意が必要なのはUTF-8(というよりUNICODE)で表現できる全ての文字がSHIFT-JISで表せないことです。SHIFT-JISで扱える文字コードは(概ね)JIS第二水準までの漢字の範囲なのでその範囲なら上記の方法でうまくいくと思います。(もっと広い範囲を扱えるかも知れませんがJIS第二水準までなら確実といえるのではないかと思います。SHIFT-JISといっても若干バリエーションがあったりして混乱しますね・・・)

しかしそれを超える範囲の文字を扱う必要があるなら、文字数と文字幅を意識しながら切り出すようなスクリプトを書かなければならないと思います。(そういうことが簡単にできるコマンドがあるかも知れませんが残念ながら自分は知りません)

投稿2017/03/27 10:54

編集2017/03/27 11:01
KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tpse

2017/03/27 15:22

やはりUFT-8以外に変換すると良いのですね。。 他の方法を知りたかったのですが、JIS第二水準までに十分収まる要件のようですので、iconvを採用します。 どうもありがとうございました。
guest

0

KSwordOfHasteさんのご回答の通り、iconvを使って一旦SHIFT-JISに変換してバイトでcut、表示用に改めてUFT-8に変換することで、綺麗に整形できました。

以前は 120バイトでカットしていましたが、見た目(SQLのform指定+ブランク)通り 113バイトでカットすることができました。

投稿2017/03/27 15:34

tpse

総合スコア11

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

SQL のスプールファイルの出力そのものをいじることができるのであれば、スプール側でカラムの区切りを設定してやって、切り出す側はその区切りを目印に行う(cut -f 区切り文字)という手が使えるかと思います。

タグにお使いのDBを追加するとよいアドバイスがもらえるかも知れません。

投稿2017/03/27 15:03

tacsheaven

総合スコア13703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tpse

2017/03/27 15:20

ご回答ありがとうございます。 可変長であれば如何様にもできるのですが、固定長を要望されていまして。。
tacsheaven

2017/03/27 15:23

いや、固定長になってないんですよね、そのスプールファイル。(固定長ならば、バイト単位で区切ればよいだけなので) スプールの出力で文字ではなくバイトで各カラムを制御してやらないと駄目ですよ?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問