目次
気づいたら1ヶ月サボってました、ごめんなさい。。。
Rustで言語処理100本ノックの第2章をはじめました。
前回はこちら。
確認用のUnixコマンド
確認用のファイルを先に生成して置きました。
これで、Rustでコードを書いて、作成済みの確認ファイルを元にassert_eq!
でチェックするという方式を取ろうかと。
で、コマンド群はこちらです。
Unix/Linuxコマンド、昔から使っています。が、なにかちょっとした文字列処理やファイル処理をやるときは、Javaのプログラム(最近だとPython)を書くというのが基本になってるので、結構、使ったことの無いコマンドが今回ありました。使ったことがなかったのはこちらです。
sed
tr
expand
paste
cut
split
sed
とかは普通さわってるだろ?って思われそうですね。。。
で、コマンドをman
で調べつつやりました、macOS上で。
これがまたいくつか罠があったので書き残しておきます(自分が知らないだけかもしれないので、おかしいところがあったらツッコミお願いします。)。
sed
コマンドでのタブの扱い
## sed command for macOS. If using Linux, use "\t" for tab character
cat $INPUT_FILE_NAME | sed -e 's/ / /g' > $OUTPUT_DIR/11_sed.txt
\t
で行けると思ったのですが、うまく動きませんでした。<tab>
みたいな書き方もあると思うのですが、これも駄目で、結局タブ文字をそのまま打ち込みました。。。
これ、めんどくさくないですか???
ちなみに、ターミナルで動作確認して、GitHubにあげてあるシェルファイルにコピペしてたのですが、CLionに貼り付けたらタブ文字がスペースに変換されてしまってて20分くらい悩みました。。。
split
コマンドに-n
オプションがない
LINES=`cat $OUTPUT_DIR/10.txt`
SPLIT_LINES=`echo $LINES/$N | bc`
split -a 1 -l $SPLIT_LINES $INPUT_FILE_NAME $OUTPUT_DIR/16_
split
コマンドについてググると、-n
で指定した数のファイルに分割できるという記事がいくつも出てくるのですが、man split
をターミナル上でやるとそんなオプションがないと。。。
macOSがBSD系だからっぽいです。
ということで、行数を元に、指定した数(N
)で行数を割ってから、指定行数ごとにファイルを分割する方式にしました。
これらのコマンドの違いはHomebrewとかでインストールするとなくなるのかなぁ?(めんどくさいので確認してないですが。。。)
ってことで、2章のそれぞれの課題の正解ファイルの生成はこれでできたはずです。
10. 行数のカウント
wc -l
ですね。
// ch02-10 行数のカウント
pub fn word_count(file_name: &str) -> usize {
let f = File::open(file_name).expect("file not found");
let buf = BufReader::new(f);
return buf.lines().count();
}
ファイルを読み込んで行数を数えます。
文字列として読み込んで改行コードの数を数えるというのもありかな?と思いましたが、RustのBufReader
にlines()
という行のイテレータ?が取れることがわかったので、それでカウントを取りました。
11. タブをスペースに置換
// ch02-11 タブをスペースに置換
pub fn tab_2_space(file_name: &str) -> String {
let mut f = File::open(file_name).expect("file not found");
let mut contents= String::new();
f.read_to_string(&mut contents).expect("read error");
return contents.replace("\t", " ");
}
こっちはファイル全体を文字列に読み込んでしまってから、文字列のreplace
で置換するという方式です。
ファイルが大きい場合にこれでいいのか?という問題がある気がしますが、まずはこの実装にしました。
やるとしたら、read
メソッドとbuffer
を用意して、少しずつ読みながら、置換して吐き出す感じでしょうか?
ちゃんとした文字コードの区切りで取れるかどうかを気にしないと行けないと思うので、思ったよりはめんどくさくなりそう。
BufReader
をつかってread_line
のほうがましかも?
まとめ
ということで、サボっていたのを再開しました。 Rustのコードを書く前に、Unixコマンドの処理に結構悩みましたw
Rustのコードとしてはファイル処理なので、今後も役立つ気がしてます。 ということで、頑張っていくぞと。
comments powered by Disqus
See Also by Hugo
- 第4章終了(言語処理100本ノック2020)
- 第3章終了(言語処理100本ノック2020)
- meteredクレートの紹介
- 第2章の12から19まで(言語処理100本ノック2020)
- 第1章の08から09まで(言語処理100本ノック2020)