「メモ」カテゴリーアーカイブ

catコマンドで改行記号確認

WindowsとMacintoshの両方で、テキストファイルをいじっていると改行記号が異なるためWindowsとMacintoshでテキストファイルの表示が異なる場合があり困ることが多い。
Macの方では、ちゃんと改行されているのに、Windowsの方のテキストエディタで開くと思ったように改行されていなかったり。

今回も博論の関係で、英文を添削業者にテキストファイルで提出したのだが、こちらがMacであちらがWindowsだったため、業者が開いたテキストファイルが、こちらの思ったように改行されていなくて困った。
なので、Macの改行記号をWindowsの改行記号に変更し、ちゃんと変更されているのかを確認する方法を備忘録のため書いておく。

テキストエディタで改行記号を確認できるエディタは、例えば、Windowsだとサクラエディタがあるが、Terminal上で改行記号を確認するときは、いつもcatコマンドを使う。

cat -e filename.txt

これだけで、改行記号を確認できる。
改行コードと改行記号、説明、対応する正規表現は以下の通り

改行コード 改行記号 説明 正規表現
LF $ Line Feed(Unix系全般) \n
CR ^M Carriage Return(Mac OS 9以前) \r
CRLF ^M$ 上記2つの合わせ技(Windows系) \r\n

こんな感じでTerminal上で確認できる。この例だと、改行記号はすべて^$Mになっているので、CRLF、つまりWindows対応の改行である。
改行記号の変換方法は、いろいろあるようだが、perlで正規表現を使って置換してやれば良い。

CRLFから、LF

perl -pi -e 's/\r\n/\n/g' *.txt

LFから、CRLF

perl -pi -e 's/\n/\r\n/g' *.txt

案外簡単。

参考リンク
https://en.wikipedia.org/wiki/Newline

NICERのテキストファイルをplain化

NICER: the Nagoya Interlanguage Corpus of English Reborn 1.0には、英語母語話者と英語学習者が執筆したエッセイファイルが収録されている。
エッセイが収録されているテキストファイルは、単に英文が収録されているわけではなく、CHAT形式で執筆者のDemographic情報やエッセイの評定、母語話者の添削、コメントなども収録されている。以下のような感じ。

@Begin
@Participants:	JPN501
@PID:	PIDJP501
@Age:	21
@Sex:	F
@YearInSchool:	U2
@Major:	agriculture
@StudyHistory:	8
@OtherLanguage:	Chinese=1.0;none=
@Qualification:	TOEIC=590(2013);none=;none=
@Abroad:	none=;none=
@Reading:	3
@Writing:	2
@Listening:	2
@Speaking:	1
@JapaneseEssay:	4
@EnglishEssayEx:	3
@EnglishEssay:	2
@Difficulty:	
@EssayTraining:	3
@SelfEval:	2
@TopicEase:	4
@Topic:	sports
@Criterion:	4
@Proctor:	1
@Comments:	
@Date:	2013-12-17
@Version:	1.0
*JPN501:	What kind of sports do you like?
%NTV:	OK
%COM:	
*JPN501:	Do you like soccer, base ball or swimming?
%NTV:	Do you like soccer, baseball, or swimming?
%COM:	"Baseball" is one word. In lists with three or more items, put a comma between each item, including one before the final "and".
*JPN501:	There are many and variety sports around the world.
%NTV:	There are many varieties of sports around the world.
%COM:	
*JPN501:	A country has some traditional sports.
%NTV:	Most countries have some traditional sports.
%COM:	
*JPN501:	Of course, there are some traditional sports in Japan.
%NTV:	OK
%COM:	
*JPN501:	They are called "BUDO".
%NTV:	They are called budo.
%COM:	This word does not require capitalization.
*JPN501:	BUDO are JYUDO, KENDO, KYUDO and so on.
%NTV:	Budo include judo, kendo, kyudo, and so on.
%COM:	These words do not require capitalization.
*JPN501:	If you play BUDO, there is an important thing that you must remember.
%NTV:	If you play budo, there is one important thing you must remember. 
%COM:	
*JPN501:	It is "REI".
%NTV:	It is rei.
%COM:	
%par:

中略

*JPN501:	We Japanese should be proud of and teach more many people around the world about this traditional sports "BUDO".
%NTV:	We Japanese should be proud of and teach many more people around the world about our traditional sports, budo.
%COM:	
@End

これはこれで有益な情報なのだが、本文を構文解析等をしたい場合は、これらの情報は不要になる。必要な情報は、

*JPN501:	What kind of sports do you like?
*JPN501:	Do you like soccer, base ball or swimming?
*JPN501:	There are many and variety sports around the world.

といった*JPN501:の本文の部分だけ。後は不要。
というわけで、CHAT形式で収録されている本文をplainテキストにする手順を備忘録として書いておく。

まず、1行目から28行目までは、執筆者のDemographic情報が収録されているので、1行目から28行目までは削除してしまえば良い。いろいろ方法があると思うが、いつもsedコマンドを使用しているので、sedコマンドで行数指定して、削除する。一つのファイルだけじゃなく、ディレクトリ内の全てに対して処理したいので、forループも使う。Terminal上で、以下を実行すると1行目から28行目まですべて削除できる。

Windowsの場合

for file in *.txt; do sed -Ei "1,28d" ${file}; done

Macの場合

for file in *.txt; do sed -Ei "" "1,28d" ${file}; done

次に、本文前のID(*JPN501の部分)や、%NTV、%COMといった、英語母語話者の添削文やコメント、最後の@Endの部分が不要。これも消したい。これは、正規表現を使用して、置換してやれば良い。

perl -pi -e 's/(%NTV:\t.+|%COM:\t.+|%COM:|\@End|\*JPN\d\d\d:\t)//g' *.txt

こうすることで、不要な情報が削除されるが、削除された場所は、空白行として残るので、その空白行も消したい。

perl -pi -e 's/^\n//g' *.txt

これで、空白行が消える。
最後に不要なのは、%par:の部分。これは、段落の改行を意味するので、最後に消さなければならない。%NTVなどと一緒に削除してしまうと、段落の部分がなくなってしまうので、段落は残しておきたい。ので、最後に%par:の部分を削除して、空白行として置き換えることで、段落を維持する。

perl -pi -e 's/%par://g' *.txt

これで、段落情報は維持したまま、不要な文字等をすべて削除し、本文だけのplainファイルが完成する。

テキストの任意の箇所に文字列挿入

博論に使うテキストデータの下処理の関係で、備忘録。

以下のようなCHAT形式のテキストファイルがあるとする。

@Begin
@Participants:	JAN0180
*JAN0180:	I do not agree with having broad knowledge of many academic subjects .
*JAN0180:	I think it is no use to learn them .
*JAN0180:	Have you ever use many academic subjects to work or live ?
%P
*JAN0180:	We learn something that is useless for us when we are students .
*JAN0180:	In fuct , I did not use knowledge that is history , biology and math to live or develope my ideas .
*JAN0180:	In addition , the thing I learned when I was a high school student is different from the things I am learning now in university .
%P
@End

やりたいことは、@Begin、@Participants、%P、@End以外の改行直後に文字列を挿入したい。例えば、今回の例だと%INSERT:という文字列を挿入したい。
この例だと、「*JAN0180:本文」という文字列の改行直後にそれぞれ%INSERTを挿入していきたい。

@Begin
@Participants:	JAN0180
*JAN0180:	I do not agree with having broad knowledge of many academic subjects .
%INSERT:
*JAN0180:	I think it is no use to learn them .
%INSERT:
*JAN0180:	Have you ever use many academic subjects to work or live ?
%INSERT:
%P
*JAN0180:	We learn something that is useless for us when we are students .
%INSERT:
*JAN0180:	In fuct , I did not use knowledge that is history , biology and math to live or develope my ideas .
%INSERT:
*JAN0180:	In addition , the thing I learned when I was a high school student is different from the things I am learning now in university .
%INSERT:
%P
@End

こんな感じで。

処理したいテキストの本文の前には、「*JAN0180」という形で、アスタリスクがついているので、そこを指定して置換すればうまくいくはず。

置換前:(\*.+\n)
置換後:$1%INSERT:\t\n

単に、アスタリスクを指定して、後方参照するだけでうまく行く。
テストでうまく行ったので、後は対象のディレクトリ内すべてのテキストファイルに対して同じ処理をする。Terminal上でperlの1行スクリプトを書いて置換してやれば一瞬で500ファイルの置換が終わった。

perl -pi -e 's/(\*.+\n)/$1%INSERT:\t\n/g' *.txt

こんな感じで。