Я модифицировал свой тезаурус для завершения предложений. Некоторые улучшения будут Завершите, используя PWD/ , Gutenberg/books/ , Лучшее регулярное выражение с использованием контекста вокруг курсора.
" What: Complete sentence
" Usage: :so % <CR> Get sentence[press C-x C-o]
" How: Get sentence completions using perl from current file
set completeopt+=menuone
set omnifunc=MoshCompleteSentence
function! MoshCompleteSentence(findstart, base)
" == First call: find-sentence-backwards, see :help omnifunc
if a:findstart
let s:line = getline('.')
let s:wordStart = col('.') - 1
" Check backward for a sentence_prefix
while s:wordStart > 0 && s:line[s:wordStart - 1] =~ '[A-Za-z0-9 _,]'
let s:wordStart -= 1
endwhile
return s:wordStart
else
" == Second call: grep for sentence_regex, output: list of sentences
let a:sentence_regex = a:base
" in regex trim spaces
let a:sentence_regex = substitute( a:sentence_regex,'\v^\s*(.{-})\s*$','\1','')
" in regex change punctuation as dot.
let a:sentence_regex = substitute(a:sentence_regex,'\W','.','g')
" grep using perl
let s:cmd='perl -ne '' '
\.'chomp;'
\.'next if m/^[;#]/;'
\.'if( /('.a:sentence_regex.'.{1,30})/io ){'
\.' print qq/$1;;/ '
\.'}'
\. ' '' '
\.expand("%:p")
" == To debug: redir echom to file
" redir >> c:/tmp/vim.log
echom s:cmd
let s:rawOutput = system(s:cmd)
let s:listing = split(s:rawOutput, ';;')
" echom join(s:listing,',')
" redir END
return s:listing
endif
endfunction
Чтобы решить актуальную проблему за один шаг:
$ grep -o '201[1-4].[0-9]\+' file1.txt file2.txt file3.txt \
| datamash --sort -t: -g1 count 2 mean 2
file1.txt:8:2012.8125
file2.txt:6:2013.08
file3.txt:7:2013.6371428571
grep
получает значения из файлов, datamash
подсчитывает элементы и вычисляет средние значения по файлам. Теперь у вас есть одна строка на файл:filename:n:average
Легче, да?
Чтобы получить среднее значение по всем файлам, удалите группировку:
grep -o '201[1-4].[0-9]\+' file1.txt file2.txt file3.txt \
| datamash --sort -t: mean 2
2013.1638095238
Если вам нужен красивый -печатный табличный вывод, попробуйте что-то вроде этого:
$ cat mktable.sh
#!/bin/bash
myfiles="$@"
trap "rm ${myfiles//txt/txt.tempfile}" EXIT SIGTERM SIGINT
declare -A count
for f in $myfiles ; do
# write the tempfile AND get the linecount simultaneously
count[$f]="$(grep -o '201[1-4].[0-9]\+' "$f" | tee ${f}.tempfile | wc -l)"
sed -i "1i $f" ${f}.tempfile # write header
sed -i "2i ---------" ${f}.tempfile # write header
done
( paste ${myfiles//txt/txt.tempfile} ;
for item in $myfiles ; do echo -n '--------- '; done; echo
for item in $myfiles ; do echo -n "n=${count[$item]} " ; done ; echo ;
for item in $myfiles ; do echo -n '--------- '; done; echo
)\
| column -nt
echo "Average: $(grep -o '201[1-4].[0-9]\+' $myfiles | datamash -s -t: mean 2)"
$./mktable.sh file*.txt
file1.txt file2.txt file3.txt
--------- --------- ---------
2012.69 2013.17 2013.54
2013.44 2012.6 2013.9
2012.64 2013.12 2013.66
2013.11 2012.76 2013.44
2012.6 2013.75 2013.89
2012.41 2013.08 2013.62
2012.41 2013.41
2013.2
--------- --------- ---------
n=8 n=6 n=7
--------- --------- ---------
Average: 2013.1638095238
Я бы обработал все это с помощью AWK:
#!/usr/bin/gawk -f
BEGIN {
RS = " +|\t+|\n"
OFS = "\t"
}
$1 >= 2011 && $1 < 2015 {
counts[FILENAME]++
allcounts++
allsum += $1
values[FILENAME][length(values[FILENAME])] = $1
}
END {
for (file in counts) {
printf "%s%s", file, OFS
if (counts[file] > maxlength) {
maxlength = counts[file]
}
}
printf "\n"
for (i = 0; i < maxlength; i++) {
for (file in counts) {
if (i < counts[file]) {
printf "%.2f", values[file][i]
}
printf "%s", OFS
}
printf "\n"
}
printf "\n"
for (file in counts) {
printf "n=%d%s", counts[file], OFS
}
printf "\n"
printf "Average: %f\n", allsum / allcounts
}
Сохраните это в файл (, например 546830
), сделайте его исполняемым(chmod 755 546830
)и запустите следующим образом:
./546830 file1.txt file2.txt file3.txt
Вы можете выровнять столбцы, используяcolumn
:
./546830 file1.txt file2.txt file3.txt | column -t
Используя примеры, приведенные в вашем вопросе, я получаю
file1.txt file3.txt file2.txt
2012.69 2013.54 2013.17
2013.44 2013.90 2012.60
2012.64 2013.66 2013.12
2013.11 2013.44 2012.76
2012.60 2013.89 2013.75
2012.41 2013.62 2013.08
2012.41 2013.41
2013.20
n=8 n=7 n=6
Average: 2013.163810
Порядок файлов на выходе не обязательно будет соответствовать их порядку на входе, но значения не будут перепутаны. Если порядок важен, я могу изменить сценарий, чтобы сохранить его.
Это работает следующим образом: каждый файл разбивается на записи по пробелам и символам новой строки, а затем сохраняется каждая запись, соответствующая критериям (между 2011 включенным и 2015 исключенным )в массиве values
, проиндексированном по файлу. имя и количество. Значения также добавляются в накопитель allsum
, а количество файлов для каждого файла -хранится в массиве counts
, а совокупное количество — в накопителе allcounts
.