С grep
:
grep -c '^[^,]*,[^0]'
Это работает, только если 2-й столбец сформирован как целое число, но не -0
, +0
. Для более общего случая см. @ Ответ Стефана Хазеласа .
Вы можете использовать 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
Вам не нужен цикл. Большинство инструментов обработки текста принимают несколько аргументов, например с sed
:
sed '/From file/{s/.*<\(.*\)>/\1/;h
}
/Ratio of morphemes over utterances/!d
s/.*= //;H;x;s/\n/\t/' ./* > outfile
Это извлекает имя файла и сохраняет его в буфере хранения, удаляет все строки, кроме тех, где извлекается "коэффициент", который он добавляет к имени файла, а затем обменивается буферами и заменяет новую строку табуляцией. Конечно, \ t
специфичен для gnu sed
, поэтому замените его буквенной вкладкой (в терминале нажмите Ctrl + V , затем ] Вкладка ), если вы не используете установку GNU
. Еще быстрее, с любым sed
:
sed '/From file/{s/.*<\(.*\)>/\1/;h
}
/Ratio of morphemes over utterances/!d
s/.*= //;H;x' ./* | paste - - > outfile
Если ваши файлы огромны, вы можете выйти при втором совпадении (строка с «соотношением») и перейти к следующему файлу. Здесь пригодится nextfile
gawk
(я думаю, что это POSIX, но не уверен, какие варианты awk
его поддерживают ...):
awk '/From file/{printf("%s\t", substr($3, 2, length($3)-2))}
/Ratio of morphemes over utterances/{print $7; nextfile}' ./* > outfile
perl -0nE 'say "$1\t$2" if /From file <(.*?)>.*over utterances = (\d\S*)/s' * > out
вы можете попробовать с помощью команды awk
awk '/Ratio of morphemes over utterances/{print FILENAME,$NF;next}' *.cha
, если вы хотите извлечь имя файла из шаблона из файла
, затем попробуйте следующую команду awk.
awk '/From file/{filename=$NF} filename && /Ratio of morphemes over utterances/{print FILENAME,$NF;filename="";next}' *.txt
Поскольку вы упомянули, что знакомы с 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 ()
, которая считывает каждый файл построчно и находит соответствующие поля. re.split ()
используется для более удобного разбиения строки имени файла на список слов, используя пробел и <
и >
в качестве разделителей слов. Сценарий может принимать аргумент командной строки для каталога, но если он не указан, предполагается текущий рабочий каталог. Таким образом, вы можете запускать скрипт по пути или из каталога, в котором хранятся файлы.Что касается создания нового файла со всеми данными, это тривиально - используйте перенаправление оболочки как ./ extract_data.py> /path/to/new_file.txt
. Предупреждение - перенаправьте сценарий в файл, расположенный в другом каталоге, поскольку новый файл может быть помещен в очередь в os.walk ()
и нарушить сценарий. Дополнительным улучшением является то, что вы можете вызывать цикл for для файлов как для f в sorted (files):
, чтобы читать файлы в отсортированном виде.