京橋のバイオインフォマティシャンの日常

南国のビーチパラソルの下で、Rプログラムを打ってる日常を求めて、、Daily Life of Bioinformatician in Kyobashi of Osaka

grepコマンドで文字列処理をやってみた件【その2】検索語のヒット数カウントとか検索語の前後文字の抽出とか色々

はじめに

grepコマンドによる文字列処理をやってみた」の続編です。

以前扱えていなかった内容をやっていきたいです。

grepコマンドの基本については過去の記事を参照のこと。

skume.hatenablog.com

まずは、サンプルデータをダウンロードする

svn export  https://github.com/kumeS/Blog/trunk/grep_practice_02

cd ./grep_practice_02

# test.txtを使っていく。
cat test.txt

#abcde
#ABCDE
#
#abcdefghijklmnopqrstuvwxyz
#ABCDEFGHIJKLMNOPQRSTUVWXYZ
#
#12345abcde67890fghij
#12345abcde67890fghij

検索語に一致した文字列のみを抜き出して出力する

grep -oを使うと、検索後と同じものが、ヒットした文字列として出力されます。

#'abc'で検索すると、5個ヒット
grep -o 'abc' test.txt
#abc
#abc
#abc
#abc
#abc

# -o を入れずに検索すると、'abc'を含む行数の4個でヒット
grep 'abc' test.txt
#abcdeabcde
#abcdefghijklmnopqrstuvwxyz
#12345abcde67890fghij
#12345abcde67890fghij

#'fghij'で検索すると、3個ヒット
grep -o 'fghij' test.txt
#fghij
#fghij
#fghij

大文字・小文字を区別せず、検索語に一致した文字列のみを抜き出して出力する

grep -o -iを使うと、大文字・小文字が区別されずに、ヒットした文字列が出力されます。

#'abc' or 'ABC'で検索され、8個ヒット
grep -o -i 'abc' test.txt
#abc
#abc
#ABC
#ABC
#abc
#ABC
#abc
#abc

# -i のみで検索すると、6個ヒット
grep -i 'abc' test.txt
#abcdeabcde
#ABCDEABCDE
#abcdefghijklmnopqrstuvwxyz
#ABCDEFGHIJKLMNOPQRSTUVWXYZ
#12345abcde67890fghij
#12345abcde67890fghij

#'fghij' or 'FGHIJ' で検索され、4個ヒット
grep -o -i 'fghij' test.txt
#fghij
#FGHIJ
#fghij
#fghij

検索語に一致した文字列の数をカウントする【部分一致検索】

grep -ogrep -cを使うと、検索語に一致した文字列数が出力されます。

このとき注意することとしてコマンドを分けずに、grep -o -cにすると、行数カウントになります。

#'abc'で検索して、'abc'をカウントすると、5個ヒット
grep -o 'abc' test.txt | grep -c 'abc'
#5

# -o -c にすると、4個ヒットで、行数カウントになる
grep -o -c 'abc' test.txt
#4

#'fghij'で検索すると、3個ヒット
grep -o 'fghij' test.txt | grep -c 'fghij'
#3

検索語に一致した箇所の前後の行を出力する

grep -Cを使うと、前後の行(行数指定)を一緒に出力できます。

#前後1行を出力する
grep -C 1 'hijklmn' test.txt
#
#abcdefghijklmnopqrstuvwxyz
#ABCDEFGHIJKLMNOPQRSTUVWXYZ

#前1行、後3行を出力する
grep  -B 1  -A 3 'hijklmn' test.txt
#123456
#abcdefghijklmnopqrstuvwxyz
#ABCDEFGHIJKLMNOPQRSTUVWXYZ
#
#12345abcde67890fghij

grep -B -Aを使うと、-Bで検索語前の行数、-Aで検索語後の行数を指定できます。

検索語に一致した箇所の前後の文字列を出力する

上記で、行レベルで出力する方法を紹介したが、 正規表現. (ピリオド)を使うと、前後の文字列も出力できます。

#検索語を抜き出して表示
grep -o 'efghijk' test.txt
#efghijk

#検索語の前4文字も含めて出力
grep -o '....efghijk' test.txt
#abcdefghijk

#検索語の後4文字も含めて出力
grep -o 'efghijk....' test.txt
#efghijklmno

#検索語の前4文字、後4文字も含めて出力
grep -o '....efghijk....' test.txt
#abcdefghijklmno

また、検索語を「変数」で指定することもできる。

TERMS=$"efghijk" ; grep -o "....$TERMS...." test.txt
#OR
TERMS=$'efghijk' ; grep -o "....$TERMS...." test.txt

#abcdefghijklmno

やってみると、'"の組み合わせが重要らしいです。

;は、複数文を繋げて書く文法である。

検索語を行番号付きで出力する

grep -nを使うと、行番号付きで出力されます。

#'abc'行を行番号付きで出力
grep -o -n 'abc' test.txt
#1:abc
#abc
#4:abc
#7:abc
#8:abc

grep -n 'abc' test.txt
#1:abcdeabcde
#4:abcdefghijklmnopqrstuvwxyz
#7:12345abcde67890fghij
#8:12345abcde67890fghij

#'fghij'行を行番号付きで出力
grep -o -n 'fghij' test.txt
#4:fghij
#7:fghij
#8:fghij

検索語の行番号のみを出力する

行番号のみを出力するには、sedとの組み合わせで行います。

#'abc'行を行番号のみ出力
grep -n 'abc' test.txt | sed -e 's/:.*//g'
#1
#4
#7
#8

#'fghij'行を行番号のみ出力
grep -n 'fghij' test.txt | sed -e 's/:.*//g'
#4
#7
#8

grepのエラーメッセージを消す

そのままではあまり使わないけど、プログラムを組むときには役に立つかもです。

#フォルダに実行するとエラーが出る
grep 'abcd' test
grep: test: Is a directory

grep -s 'abcd' test
#OR
grep --no-messages 'abcd' test
#エラーメッセージの非表示

まとめ

grepコマンドは結構役に立つので、一通り覚えておくと、 いろいろなテキストの前処理とかに使えそうです。

補足

正規表現のまとめ

正規表現 (Regular Expression)は、文字列のパターン・マッチングなどの表記法として使用する。

また、メタキャラクタとは、文字列のパターンを表す特殊な記号のことを指す。

メタキャラクタ そのメタキャラクタが意味すること
. 任意の一文字
* 前にある文字の0回以上の繰り返し
+ 前にある文字の1回以上の繰り返し
? 前にある文字の0回あるいは1回の意味
^ 指定した文字が文頭
$ 指定した文字が文末
[ ] 指定した複数の文字の中のいずれか
{ } 前にある文字の指定した回数の繰り返し
\w 英数文字またはアンダーバー。[a-zA-Z0-9_]と同等
\W \w 以外の文字
\d 数値文字。[0-9]と同等
\D 数値以外の文字。[^0-9]と同等
\s 空白文字
\S 空白以外の文字
\b ワードの先頭、あるいは末尾にマッチ
\B ワード内の文字列にマッチ
\A 文字列の最初にマッチ
\Z 文字列の最後にマッチ
\t タブ
\n 改行
\r キャリッジリターン

参考

www.wakuwakubank.com

webplus8.com

www.gadgety.net

grepコマンドで文字列処理をやってみた件【その1】ファイル内のテキストに対する処理とか

はじめに

grepコマンドは、ある特定の文字列を含むものを取り出す・検索するときに使用します。 大別して、ファイル内のテキストに対してgrepを行うか、ファイル名に対してgrepを行うかでやり方が変わってきます。

やってることは単純だが、いろいろと応用できるので、今回まとめてみました。

練習用のファイルのダウンロード

練習用のファイル・フォルダを以下のコマンドでダウンロードできるようにしています。

#ダウンロード
svn export  https://github.com/kumeS/Blog/trunk/grep_practice

#作業フォルダに移動
cd ./grep_practice

ファイル内のテキストに対する処理

ある特定の文字列を含む行を表示する

#ファイル内の表示
cat test_01.txt

#'abc'を含む行を出力する
grep 'abc' test_01.txt
#OR
grep "abc" test_01.txt
#OR
cat test_01.txt | grep 'abc'

ある特定の文字列を含まない行を表示する

#'abc'を含まない行を出力する
grep -v 'abc' test_01.txt 
#OR
cat test_01.txt | grep -v "abc"

ある特定の文字列を含まない行を別ファイルに出力する

#'abc'を含まない行を「test_01_v.txt」として保存する
grep -v 'abc' test_01.txt > test_01_v.txt

#test_01_v.txtの表示
cat test_01_v.txt

オプション

-v: 文字列を含まない、あるいは、一致しないものを検索する

空白行を削除する

#空白行を含まない行の表示
cat test_02.txt | grep -v '^\s*$'

#別ファイルで保存する場合
cat test_02.txt | grep -v '^\s*$' > test_02_r.txt

オプション

^: 行頭

\s: 空白文字

^\s*: 行頭から0回以上繰り返しの空白

ファイル内の行数をカウントする

#ファイル内全体の行数のカウント
cat test_01.txt | grep '' -c

#grepを使わない方法
cat test_01.txt | wc -l

#'abc'を含む行数のみのカウント
cat test_01.txt | grep 'abc' -c

オプション

-c: 行数とかのカウント

複数条件で、文字列の検索をする場合

grepでのAND検索

cat test_02.txt

#AND検索
#'AAA'と'ABB'を同行に含む行の表示
grep 'AAA' test_02.txt | grep 'ABB'

grepでのOR検索

cat test_02.txt

#OR検索(-e表記)
#'AAA'あるいは'BBB'を含む行の表示
grep -e 'AAA' -e 'BBB' test_02.txt

#OR検索(正規表現、\| を使う)
#'AAA'あるいは'BBB'を含む行の表示
grep 'AAA\|BBB' test_02.txt

オプション

-e: 検索パターンを指定する

-w: 単語全体でパターンと一致するものを検索する

-x: 行全体がパターンと一致するものを検索する

-i: 大文字と小文字を区別しない

-n: 検索結果に行番号を表示する

ファイル名に対する処理

ある特定の文字列をファイル名に含むファイルを検索する

#ディレクトリ内ファイルの表示
ls

#.txtファイルのみを表示する
ls | grep '.txt'
#.txtファイルのカウント
ls | grep '.txt' | wc -l

#ファイル内の行、ワード、バイトの各カウントの表示
ls | grep 'test_01.txt' | wc
#OR
wc test_01.txt

オプション

-l: ファイル名を検索対象とする

サブディレクトリも含めて検索する

#'.pdf'を含むファイル数のカウント
ls | grep '.pdf' | wc -l

#サブディレクトリを含めたファイル表示
du -a

#サブディレクトリを含めて、'.pdf'を含むファイルの表示
du -a | grep '.pdf'

#サブディレクトリを含めて、ファイル数のカウント
du -a | grep '.pdf' | wc -l

特定のファイルを検索して、消去する

#ディレクトリ内の'.pdf'を含むファイルを消去する
ls | grep '.pdf' | xargs rm -rf

#サブディレクトリも含めて削除する場合
du -a | grep '.pdf' | xargs rm -rf

ここで、 xargs は、前のコマンドの実行結果を引数にして、次のコマンド rm に渡すことを意味します。

補足

ターミナル・ショートカット

カーソルの移動
Ctrl + b 後退・一語後退
Ctrl + f 前進・一語前進
Ctrl + a 行頭へ移動
Ctrl + e 行末へ移動
削除
Ctrl + w 単語1個文削除
Ctrl + k 行末まで削除
Ctrl + u 行頭まで削除
Ctrl + d カーソル上の1文字削除
Ctrl + h カーソルの後方を1文字削除
履歴
一つ前のコマンド履歴
次のコマンド履歴
history (コマンド) 履歴
その他
Ctrl + c 実行中のコマンドを強制終了
Ctrl + z 実行中のコマンドを一時停止
Ctrl + d 終了、Logout
Ctrl + l 画面をクリアする
Ctrl + t 一つ前とカーソルの文字の入替
Ctrl + m, Ctrl + j, Ctrl + o Enter

cd : ディレクトリ移動

cat : ファイル内表示・結合・作成

#テキストファイル(test.txt)内の表示
cat test.txt

#行番号を付加して、ファイル表示
cat -n test.txt

#複数ファイルから、結合ファイルを作成(行方向に結合)
cat test1.txt test2.txt > test3.txt

#空ファイルの作成(Ctrl + d で終了すること)
cat > test4.txt

#すべての履歴表示、「~ (チルダ)」はHomeディレクトリ
cat ~/.bash_history
#OR
history

head / tail : ファイルの先頭や末尾を表示

#ファイルの先頭から、10行を表示
head -n 10 test.txt

#ファイルの末尾から、10行を表示
tail -n 10 test.txt

覚えておくと良いターミナルコマンド

#システムを終了する
shutdown -f now
              
#再起動する
reboot

#すべてのユーザーに実行権限を与える
chmod a+x test.command

#Rootユーザーでコマンドを実行する
sudo ...

その他のターミナルコマンド

#日時を表示するコマンド。
date

#2012年のカレンダーを表示する
cal 2020

#アクティブなジョブの表示
jobs

関連記事

skume.net

htmlwidgets for R のShowcaseにあるパッケージがCodePenでブログ表示できるかを調べた件

はじめに

htmlwidgets for R パッケージは、Rでインタラクティブな図が作成できる王道的なパッケージであり、 それを使った色々な依存パッケージが開発されています。

www.htmlwidgets.org

今回、htmlwidgetsのshowcaseにある12パッケージをHatena Blog内の図表として表示するにあたって、(1)Html 出力の可否 、(2)CodePen対応できるか?、さらには(3)ブログ表示できるか?を調べてみました。

CodePenとは、ユーザーが作成したHTML、CSS、JavaScriptのコードスニペットのテスト、 および披露をするオンラインツールの1つです。

とりあえず、結果

パッケージ html output CodePen はてなブログ表示
Leaflet 473KB
Dygraphs 574KB
Plotly 3.5MB X X
rbokeh 955KB X X
Highcharter 995KB X X
visNetwork 1.1MB X X
networkD3 263KB
d3heatmap 229KB
DataTables 207KB
threejs 977KB X X
rglwidget X X X
DiagrammeR 2.5MB X X
MetricsGraphics 368KB

表示結果

Leaflet

Rスクリプト

if(!require("leaflet")){install.packages("leaflet")}; library(leaflet)
if(!require("magrittr")){install.packages("magrittr")}; library(magrittr)

m <- leaflet() %>%
  addTiles() %>%  # Add default OpenStreetMap map tiles
  addMarkers(lng=174.768, lat=-36.852, popup="The birthplace of R") 
m

CodePenでの出力結果

See the Pen leaflet by skume (@kumes) on CodePen.

Dygraphs

Rスクリプト

if(!require("dygraphs")){install.packages("dygraphs")}; library(dygraphs)
if(!require("magrittr")){install.packages("magrittr")}; library(magrittr)

dygraph(nhtemp, main = "New Haven Temperatures") %>% 
  dyRangeSelector(dateWindow = c("1920-01-01", "1960-01-01"))

CodePenでの出力結果

See the Pen dygraph by skume (@kumes) on CodePen.

networkD3

Rスクリプト

if(!require("networkD3")){install.packages("networkD3")};
library(networkD3)
if(!require("magrittr")){install.packages("magrittr")}; library(magrittr)

data(MisLinks, MisNodes)
forceNetwork(Links = MisLinks, Nodes = MisNodes, Source = "source",
             Target = "target", Value = "value", NodeID = "name",
             Group = "group", opacity = 0.4)

CodePenでの出力結果(Run Pen クリック必要)

See the Pen networkD3 by skume (@kumes) on CodePen.

d3heatmap

Rスクリプト

if(!require("d3heatmap")){install.packages("d3heatmap")}; library(d3heatmap)

d3heatmap(mtcars, scale="column", colors="Blues")

CodePenでの出力結果

See the Pen d3heatmap by skume (@kumes) on CodePen.

DataTables

Rスクリプト

if(!require("DT")){install.packages("DT")}; library(DT)

datatable(iris, options = list(pageLength = 5))

CodePenでの出力結果

See the Pen datatable by skume (@kumes) on CodePen.

MetricsGraphics

Rスクリプト

if(!require("metricsgraphics")){install.packages("metricsgraphics")}; library(metricsgraphics)
if(!require("magrittr")){install.packages("magrittr")}; library(magrittr)

mjs_plot(mtcars, x=wt, y=mpg) %>%
  mjs_point(color_accessor=carb, size_accessor=carb) %>%
  mjs_labs(x="Weight of Car", y="Miles per Gallon")

CodePenでの出力結果

See the Pen metricsgraphics by skume (@kumes) on CodePen.

まとめ

CodePenの1MB制限で、Plotly、rbokeh、Highcharter、visNetwork、threejs、DiagrammeRがCodePenで保存できない。

うすうす気付いてたけど、Plotlyのhtml出力はやや重過ぎるので、Webコード共有には不向き。

visNetworkの結果は貼付できないけど、networkD3の結果は貼付できるという不思議な結果になった。。

CodePenでの保存ができると、だいたいブログでも表示できるっぽい。