« ワンライナーで実践する簡単データ処理(その1 繰り返し項目集計編) | トップページ | tsvファイルからShell Scriptやコマンドを組み合わせてJSON生成 »

2018.09.22

ワンライナーで実践する簡単データ処理(その2 疑似データベース編)

この記事は、ワンライナーで実践する簡単データ処理(その1 繰り返し項目集計編)の続きです。

前回作成したtemp01.txtはこのようなファイルでした。


WOS:000207567300006 [Goldfarb, Donald] Columbia Univ, Dept Ind Engn & Operat Res, New York, NY 10027 USA
WOS:000207567300006 [Osher, Stanley; Darbon, Jerome] Univ Calif Los Angeles, Dept Math, Los Angeles, CA 90095 USA
WOS:000207567300006 [Yin, Wotao] Rice Univ, Dept Computat & Appl Math, Houston, TX 77005 USA
WOS:000207567500003 [Wang, Yilun; Yin, Wotao; Zhang, Yin] Rice Univ, Dept Computat & Appl Math, Houston, TX 77005 USA
WOS:000207567500003 [Yang, Junfeng] Nanjing Univ, Dept Math, Nanjing 210093, Jiangsu Prov, Peoples R China
...

ですが、著者の項が繰り返し項目になっているため、アクセッション番号、所属機関、所属機関の国籍/地域、著者のテーブルに加工してみましょう。

$ TAB=$(printf '\t');LF=$(printf '\\\012_');LF=${LF%_};cat temp01.txt | sed 's/^\(.*\)'"$TAB"'\[\(.*\)\] \(.*\)$/\1'"$TAB"'\3'"$TAB"'\2/' | awk -F '\t' 'BEGIN{OFS="\t"}{c=split($2,a,", ");print $1, a[1], a[c], $3}' | sed 's/^\(.*\)'"$TAB"'\(.*\)'"$TAB"'.*USA'"$TAB"'\(.*\)$/\1'"$TAB"'\2'"$TAB"'USA'"$TAB"'\3/' | sed 's/; /'"$LF"'/g' | awk -F '\t' 'BEGIN{OFS="\t"}{if(NF==4){P1=$1;P2=$2;P3=$3;print $1,$2,$3,$4}else{print P1,P2,P3,$1}}' | sort | uniq > temp02.txt

TAB=$(printf '\t');LF=$(printf '\\\012_');LF=${LF%_}
変数TAB、変数LFにそれぞれ、タブコードと改行コードを格納します。

cat temp01.txt
temp01.txtの内容を後続のコマンドに流します。

sed 's/^\(.*\)'"$TAB"'\[\(.*\)\] \(.*\)$/\1'"$TAB"'\3'"$TAB"'\2/'
temp01.txtの1カラム目、及び2カラム目の所属機関とその住所、[]内の著者の項をタブ区切りの3つの項を持つテキストデータに変換します。

awk -F '\t' 'BEGIN{OFS="\t"}{c=split($2,a,", ");print $1, a[1], a[c], $3}'
前のコマンドによる出力データの2カラム目(所属機関とその住所)に含まれる所属機関名及び国籍/地域、著者を出力します。

sed 's/^\(.*\)'"$TAB"'\(.*\)'"$TAB"'.*USA'"$TAB"'\(.*\)$/\1'"$TAB"'\2'"$TAB"'USA'"$TAB"'\3/'
USAのみ国名に州が付加されるので、州を削除します。

sed 's/; /'"$LF"'/g'
著者がセミコロン区切りの繰返し項目なので、セミコロンを改行に変換します。

awk -F '\t' 'BEGIN{OFS="\t"}{if(NF==4){P1=$1;P2=$2;P3=$3;print $1,$2,$3,$4}else{print P1,P2,P3,$1}}'
著者のみの行に、アクセッション番号($1)、所属機関($2)、国籍/地域($3)を付加します。それ以外は、そのまま出力します。

sort
後続uniqコマンドの準備としてソートします。

uniq
重複排除します。
※ 同一大学の中で複数学部に属することなどにより同一人物が重複することがあるため。

結果は、以下のようなテキストファイルtemp02.txtができます。


WOS:000207567300006 Columbia Univ USA Goldfarb, Donald
WOS:000207567300006 Rice Univ USA Yin, Wotao
WOS:000207567300006 Univ Calif Los Angeles USA Darbon, Jerome
WOS:000207567300006 Univ Calif Los Angeles USA Osher, Stanley
WOS:000207567500003 Nanjing Univ Peoples R China Yang, Junfeng
WOS:000207567500003 Rice Univ USA Wang, Yilun
WOS:000207567500003 Rice Univ USA Yin, Wotao
WOS:000207567500003 Rice Univ USA Zhang, Yin
...

次のコマンドで著者ランキング表示ができます。


$ cat temp02.txt | cut -f2,3,4 | sort | uniq -c | sort -k1nr | less


62 Victoria Univ Australia Shi, Peng
47 Univ Adelaide Australia Shi, Peng
37 Liaoning Univ Technol Peoples R China Tong, Shaocheng
37 Univ Technol Sydney Australia Tao, Dacheng
31 Southeast Univ Peoples R China Cao, Jinde
28 Chinese Acad Sci Peoples R China Li, Xuelong
27 Hong Kong Polytech Univ Peoples R China Zhang, Lei
27 Univ Glamorgan Wales Shi, Peng
26 Harbin Inst Technol Peoples R China Gao, Huijun
26 Harbin Inst Technol Peoples R China Wu, Ligang
...

次に、著者を指定して、その著者の論文タイトルと論文誌、発行年を表示させてみましょう。

savedrecs_0001_2440.txtの9カラム目が論文タイトル、10カラム目が論文誌、45カラム目が発行年、63カラム目がアクセッション番号とします。


$ cat savedrecs_0001_2440.txt | cut -f9,10,45,63 | sed '1,1d' | awk -F'\t' 'BEGIN{OFS="\t"}{print $4,$1,$2,$3}' | sort -k1 > temp03.txt

cat savedrecs_0001_2440.txt
savedrecs_0001_2440.txtの内容を後続のコマンドに流します。

cut -f9,10,45,63
9カラム目(論文タイトル)、10カラム目(論文誌名)、45カラム目(発行年)、63カラム目(アクセッション番号)を抽出します。

sed '1,1d'
1行目はタイトル行なので削除します。

awk -F'\t' 'BEGIN{OFS="\t"}{print $4,$1,$2,$3}'
アクセッション番号、論文タイトル、論文誌名、発行年の順に項目を並び替えます。

sort -k1
1カラム目でソートします。

temp03.txtの内容は次のとおり。
WOS:000207567300006     Bregman Iterative Algorithms for l(1)-Minimization with Applications to Compressed Sensing      SIAM JOURNAL ON IMAGING SCIENCES        2008
WOS:000207567500003     A New Alternating Minimization Algorithm for Total Variation Image Reconstruction       SIAM JOURNAL ON IMAGING SCIENCES        2008

著者の欄にHinton博士が入った論文を表示させてみます。


$ cat temp02.txt | awk -F '\t' 'BEGIN{OFS="\t"}$4~/Hinton/{print $0}' | join -1 1 -2 1 -t "$(printf '\t')" -o 1.2,1.3,1.4,2.2,2.3,2.4 temp03.txt - | less

cat temp02.txt
temp02.txtの内容を後続のコマンドに流します。

awk -F '\t' 'BEGIN{OFS="\t"}$4~/Hinton/{print $0}'
temp02.txtの4カラム目(著者)に'Hinton'が入った行を出力します。

join -1 1 -2 1 -t "$(printf '\t')" -o 1.2,1.3,1.4,2.2,2.3,2.4 temp03.txt -
temp02.txtの4カラム目に'Hinton'が入った行について、temp03.txt中で対応する行と結合して表示します。ここでは、temp03.txtがファイル1に対応することに注意。
-1 1
ファイル1(temp03.txt)の1行目をキーにします。
-2 1
ファイル2(パイプを介して入力)の1行目をキーにします。
-t "$(printf '\t')"
区切り文字にタブを設定します。
-o 1.2,1.3,1.4,2.2,2.3,2.4
temp03.txtの2カラム目(論文タイトル)、3カラム目(論文誌)、4カラム目(発行年)、ファイル2(パイプ)の2カラム目(所属機関)、3カラム目(所属機関の国籍/地域)、4カラム目(著者)を出力します。

今度は所属機関の国籍/地域に'Japan'が入った論文一覧を表示します。


$ cat temp02.txt | awk -F '\t' 'BEGIN{OFS="\t"}$3~/Japan/{print $0}' | join -1 1 -2 1 -t "$(printf '\t')" -o 1.2,1.3,1.4 temp03.txt - | uniq | less

cat temp02.txt
temp02.txtの内容を後続のコマンドに流します。

awk -F '\t' 'BEGIN{OFS="\t"}$3~/Japan/{print $0}'
3カラム目(所属機関の国籍/地域)に'Japan'が入った行を出力します。

join -1 1 -2 1 -t "$(printf '\t')" -o 1.2,1.3,1.4 temp03.txt -
temp03.txtとパイプを介した結果を結合します。

uniq
temp02.txtの中では同一論文が複数行になるので、重複排除します。

結果の例は次のとおり。


Cognitive Developmental Robotics: A Survey IEEE TRANSACTIONS ON AUTONOMOUS MENTAL DEVELOPMENT 2009
Top 10 algorithms in data mining KNOWLEDGE AND INFORMATION SYSTEMS 2008
Accelerating differential evolution using an adaptive local search IEEE TRANSACTIONS ON EVOLUTIONARY COMPUTATION 2008
Asymptotic Equivalence of Bayes Cross Validation and Widely Applicable Information Criterion in Singular Learning Theory JOURNAL OF MACHINE LEARNING RESEARCH 2010
...

※ おまけ
joinコマンドの重要なオプションを追記。
-a 1
ファイル1を全行表示します。LEFT OUTER JOINに対応。
-a 2
ファイル2を全行表示します。RIGHT OUTER JOINに対応。
-a指定がなければ、INNER JOINに対応。
-e '*'
JOINできずにNULLになった列に詰める文字列を指定。ここでは'*'を指定している。
-v 1
JOINできなかったファイル1の行を表示。
-v 2
JOINできなかったファイル2の行を表示。

|

« ワンライナーで実践する簡単データ処理(その1 繰り返し項目集計編) | トップページ | tsvファイルからShell Scriptやコマンドを組み合わせてJSON生成 »

パソコン・インターネット」カテゴリの記事

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック

この記事のトラックバックURL:
http://app.f.cocolog-nifty.com/t/trackback/1024423/74238378

この記事へのトラックバック一覧です: ワンライナーで実践する簡単データ処理(その2 疑似データベース編):

« ワンライナーで実践する簡単データ処理(その1 繰り返し項目集計編) | トップページ | tsvファイルからShell Scriptやコマンドを組み合わせてJSON生成 »