NLP、その前に。 Linuxコマンドで行う文字列処理

http://slides.com/yuutawatanabe/nlp-linux#/
　※Webプレゼンテーション資料の作成・投稿サイト「slides.com」を利用。

## NLP、その前に。Linuxコマンドで行う文字列処理

### 前処理が9割
* NLPツール (ex.MaCab/CaboCha) ← 前提となるデータ
* 前処理 = 前提となるデータを作る処理
* テキスト処理 = 前処理の一部

Aさん「こnnniちは。久しぶりですね。」
Bさん「お久しぶりです。お元気でしたか？」
Aさん「こちらは変わりありません。Bさんは？」
Bさん「こちらも変わりありません。」
　↓　加工・抽出
こんにちは。久しぶりですね。
こちらは変わりありません。Bさんは？

### 定番のテキスト処理ツール = Linuxコマンド
* データ整形コマンドの数が多い。
* RubyやPythonよりも楽に書ける場合も多い。
* Windowsの場合は、[Cygwin](https://www.cygwin.com/)を通して利用する。

### Demo

```bash
sed '1,/class="main_text"/ d' 羅生門.html | sed '/class="bibliographical_information"/,$ d' | sed 's/[<][^>]*>//g' | sed 's/ \|（.\+）//g' | tr -s '\n' > 羅生門.txt
```
 
※羅生門.html = [青空文庫「芥川龍之介 羅生門」](http://www.aozora.gr.jp/cards/000879/files/127_15260.html)

## 前処理を簡潔にする事で、やりたい事に注力できるようにしよう！

### Linuxコマンドの書式
**コマンド名 -オプション 引数**

```bash:【例】
# Hello World! と表示
echo -e "Hello\tWorld!"
```

## 強力な構文、リダイレクションとパイプ。

### 出力リダイレクション(>, >>, >&)
**コマンド > 出力先**
コマンドの結果を出力先に書き込みます。

**コマンド >> 出力先**
コマンドの結果を出力先に追記します。

**コマンド >& 出力先**
コマンドの結果やエラー内容を出力先に書き込みます。

```bash:【例】INPUT.txtから改行を削除し、OUTPUT.txtに結果を書き込む。
tr -d "\n" < INPUT.txt > OUTPUT.txt
```

### 入力リダイレクション(<)
**コマンド < 入力元**
コマンドの引数の入力元を変えます。  
入力元にファイル名を指定する事で、内容をコマンドの引数に渡せます。

```bash:【例】INPUT.txtの内容から改行を削除し、ターミナルに表示する。
tr -d "\n" < INPUT.txt
```

### パイプ(|)
**コマンド | 次のコマンド**
コマンドの結果を文字列として渡します。

```bash:【例1】INPUT.txtの内容から改行を削除し、ターミナルに表示する。
cat INPUT.txt | tr -d "\n"
```

**​​コマンド | xargs 次のコマンド**
コマンドの結果を評価値(ターミナルにタイプした値)として渡します。

```bash:【例2】INPUTフォルダ内のファイルを一覧し、先頭行を表示していきます。
find ./INPUT -type f | xargs head -n 1
```

## 強力なコマンド、テキスト処理を１文で。

### ファイル取得

**wget**
wget (url)

```bash:【例】
wget http://www.aozora.gr.jp/cards/000879/files/127_15260.html
```

　……指定URLのファイルをダウンロードする。

### ファイル結合

**cat**
cat (入力ファイル1) (入力ファイル2) ……

```bash:【例】
cat P_1.txt P_2.txt
```

　……前ファイルの内容の後ろに後ファイルの内容を加え、新しい文字列を作る。

**paste -d '\n'**
paste -d '\n' (入力ファイル1) (入力ファイル2) ……

```bash:【例】
paste -d '\n' P1.txt P2.txt
```

　……前ファイルの行ごとに後ファイルの行を挿入し、新しい文字列を作る。

**join**
join (入力ファイル1) (入力ファイル2) ……

```bash:【例】
join P1.txt P2.txt
```

　……前後ファイルを指定の列をキーにして結びつけ、新しいテーブルデータを作る。

### 文字コード変換

**nkf**
nkf -(入力文字コード)(出力文字コード) (入力ファイル)

```bash:【例】
nkf -Sw sjis.txt
```

　……ファイルの文字コードを変換する。（-Swをオプションにする事で、SJISからUTF8へ変換できます）

### 文字列操作
**sed i,sed a**
sed "(行範囲 or 対象行に一致する正規表現)i (出力文字列)"
       入力ファイル
sed "(行範囲 or 対象行に一致する正規表現)a (出力文字列)"
       入力ファイル

```bash:【例】
#2行目の前に"章題1"を挿入
sed "2i 章題1" P_BEF.txt
#3行目以降、5行ごとに"-----"を挿入
sed "3~5a -----" P_BEF.txt 
```
 
　……行を挿入する。（iで行前へ、aで行後へ）

**sed d**
sed "(行範囲 or 対象行に一致する正規表現)d" 入力ファイル

```bash:【例】
#2行目から5行目を削除
sed "2,5d" P_BEF.txt 
```

　……行を削除する。

**sed s**
sed
  "s/(行範囲 or 対象文字列に一致する正規表現)
     /(置換文字列)
     /(置換文字列の出現順 ※省略時は1番目)"
  入力ファイル

```bash:【例】
#"章題<数値>"を"章タイトル<数値>"に置換
sed "s/^章題(\([:digit:]+\))/章タイトル(\1)/" P_BEF.txt
```

　……行ごとに置換する。

**grep**
grep (対象文字列に一致する正規表現) 入力ファイル

```bash:【例】
grep "^私" P.txt
```

　……正規表現で一致した文字列がある行のみを出力する。

**tr -s**
tr -s (重複文字) < 入力ファイル

```bash:【例】
tr -s '\n' < P.txt
```

　……連続した同じ文字を1文字に置換する。

**head -n**
head -n (行数) (入力ファイル)

```bash:【例】
head -n 3 P.txt
```

　……ファイルの頭から指定行数を出力する。

**tail -n**
tail -n (行数) (入力ファイル)

```bash:【例】
tail -n 3 P.txt
```

　……ファイルの末から指定行数を出力する。

**cut -d**
cut -d (区切り文字) -f (出力列) (入力ファイル)

```bash:【例】
cut -d " " -f 2-3 P.txt
```

　……指定の区切り文字で区切られたテーブルデータから指定の列のみを出力する。

**wc -l**
wc -l (入力ファイル)

```bash:【例】
wc -l P.txt
```

　……指定ファイルの行数を数える。

**wc -w**
wc -w (入力ファイル)

```bash:【例】
wc -w P.txt
```

　……指定ファイルの単語数を数える。（英語のみ）

###より発展的な文字列操作をするなら……

**awk**
awk -F '(区切り文字)' '入力パターン{操作内容}……'

```bash:【例】
#1列目が"A〜"の行の3列目・2列目を出力する。
awk -F ' ' 'match($1, /A.*/) {print $3,$2}' P.txt
```

　……入力パターンと一致する行を操作内容で書いた操作を施して出力する。

## Enjoy NLP!