複数のファイルの特定の行から2つの文字列を抽出し、タブで区切られた新しいファイルとして印刷する必要があります。

複数のファイルの特定の行から2つの文字列を抽出し、タブで区切られた新しいファイルとして印刷する必要があります。

私はUnixとPythonの経験を持っていますが、まだ見慣れていて、それについて十分に知っていません。

複数のファイルを含むフォルダがあり、各ファイルから2つの特定の文字列を抽出し、それらの間にタブを持つ新しいテキストファイルとして印刷する必要があります。ファイルは次のようになります。

mlu +t*CHI +f
Thu Jan 12 16:27:40 2017
mlu (08-Jan-2016) is conducting analyses on:  
  ONLY dependent tiers matching: %MOR;
****************************************
From file <adam01.cha>
MLU for Speaker: *CHI:
  MLU (xxx, yyy and www are EXCLUDED from the utterance and morpheme counts):
    Number of: utterances = 1236, morphemes = 2735
    Ratio of morphemes over utterances = 2.213
    Standard deviation = 1.300

ファイル名と「タイプ対発話比」の値を抽出する必要があります。だから私はこの文字列を取り出し、次のような新しいファイルを作成したいと思います。

adam01.cha    2.213
adam02.cha    2.547
...

ここで正確に何をすべきかわかりません。どこから始めるべきかさえわかりません。 egrep、awk、またはsedが最良の選択であるかどうか、ファイルを正しく繰り返すforループにそれらを置く方法を決定することはできません。

答え1

現在のフォルダ内の各ファイルに対してループ内でsedを使用できます。関連部分を抽出して次のファイルに追加します>>file

for files in *; \
do sed -n -e '/^From file/ H;' \
          -e '/Ratio of morphemes over utterances/ {H; x; s/\n//g; s/From file <\(.*\)>.*Ratio of morphemes over utterances = \([0-9]*\.[0-9]*\).*/\1:    \2/g; p;}' "$files";
done >>file

答え2

perl -0nE 'say "$1\t$2" if /From file <(.*?)>.*over utterances = (\d\S*)/s' * > out

答え3

Pythonに精通していると述べたので、以下はそのタスクを実行するPythonスクリプトです。

#!/usr/bin/env python
from __future__ import print_function
import os,re,sys

def read_file(filepath):
    with open(filepath) as fd:
         for line in fd:
             clean_line = line.strip()

             if 'From file' in clean_line:

                 words = re.split('<|>| ', clean_line)
                 print(words[-2],end=" ")

             if 'Ratio of morphemes over utterances' in clean_line:
                 print(clean_line.split('=')[-1])



def find_files(treeroot):
    selfpath = os.path.abspath(__file__)
    for dir,subdirs,files in os.walk(treeroot):
         for f in files: 
             filepath = os.path.abspath(os.path.join(dir,f))
             if selfpath  ==  filepath: continue
             try:
                 read_file(filepath)
             except IOError:
                 pass
def main():
    directory = '.'
    if len(sys.argv) == 2:
       directory = sys.argv[1]
    find_files(os.path.abspath(directory))

if __name__ == '__main__': main()

実行例:

$ ./extract_data.py                                                                                               
adam02.cha  2.547
adam01.cha  2.213

仕組みは簡単です。os.walkディレクトリを再帰的に移動してすべてのファイルを見つけ、スクリプト自体を除いて、各ファイルに対して各ファイルをread_file()1行ずつ読み込み、適切なフィールドを見つける関数を実行します。スペースと単語区切り文字を使用して、re.split()ファイル名文字列を単語リストとしてより便利に分割するために使用されます。スクリプトはディレクトリのコマンドライン引数を取ることができますが、指定しない場合は現在の作業ディレクトリと見なされます。これにより、パスを指定したり、ファイルが保存されているディレクトリからスクリプトを実行できます。すべてのデータを含む新しいファイルを作成するのは簡単です。シェルのリダイレクトを 。追加の改善点は、ファイルのforループを呼び出すことで、ソートされた方法でファイルを読み取ることができることです。<>./extract_data.py > /path/to/new_file.txtos.walk()for f in sorted(files):

答え4

awkコマンドを試すことができます

awk '/Ratio of morphemes over utterances/{print FILENAME,$NF;next}' *.cha

パターンからファイル名を抽出したい場合<adam01.cha>ファイルから

次に、以下のawkコマンドを試してください。

awk '/From file/{filename=$NF} filename && /Ratio of morphemes over utterances/{print FILENAME,$NF;filename="";next}' *.txt

関連情報