Вот черновик сценария оболочки, написанный на Perl, который будет эмулировать PTY (так что rsync должен вести себя точно так же, как и в терминале), и анализирует вывод, чтобы он мог продолжать работать. двухстрочное отображение имени файла и статуса передачи. Это выглядит так:
src/test.c
142 100% 0.19kB/s 0:00:00 (xfr#28, to-chk=0/30)
Первая строка (имя файла, src / test.c
) будет изменяться в зависимости от текущего имени файла, выводимого rsync
. Вторая строка будет изменяться всякий раз, когда rsync
выводит обновленную строку состояния.
NB: Я выбрал двухстрочный дисплей (но тот, который по-прежнему не будет прокручиваться!) Вместо однострочного дисплея, поскольку, по крайней мере, при моем обычном использовании я получаю длинный путь / имена файлов это было бы слишком широко в сочетании со строкой состояния. Однако, как вы увидите ниже, было бы легко изменить объединение имени файла / пути и статуса в одну строку.
Когда rsync
завершается, сценарий завершается с тем же кодом выхода (так что вы все еще можете перехватывать ошибки и т. Д.)
Основано на обсуждениях с OP, встроенный rsync
были неадекватными, их версия rsync
старше, а их потребности уникальны. Таким образом, я чувствовал, что собственный сценарий был единственным способом достичь их цели.
Другой вариант - использовать любую из множества существующих rsync
утилит-оболочек «резервного копирования», которые уже существуют, хотя я не знаю ни одной, поддерживающей аналогичный вывод.
#!/usr/bin/env perl
# Custom progress wrapper for rsync
use 5.012;
use strict;
use warnings;
use autodie;
use IPC::Run qw/run start pump finish harness/;
my $RSYNC=`which rsync`; # Try to get rsync location from PATH
chomp $RSYNC;
my ($in,$out); # Input and output buffers
my $h = harness [ $RSYNC, @ARGV ], 'pty>', \$out;
local $| = 1; # Autoflush output
print "\n\n\e[2A\e[s"; # Make room and save cursor position
my ($file, $status) = ('',''); # Will hold filename and status lines
while ($h->pump) { parse() }
parse(); # Don't miss leftover output
$h->finish;
exit $h->result; # Pass through the exit code from rsync
# Parse and display file/status lines from rsync output
sub parse {
for (split /[\n\r]+/, $out) {
$file = $_ if /^\S/;
$status = $_ if /^\s/;
print "\e[u\e[0J$file\n$status\n";
}
$out = ''; # Clear output for next pump
}
Для сценария требуются два нестандартных модуля: IPC :: Run
и IO :: Pty
.Оба они могут быть установлены с помощью cpan
, который поставляется с Perl. Многие, в том числе и я, предпочитают cpanm
, который можно установить с помощью следующего однострочника:
curl -L https://cpanmin.us | perl - App::cpanminus
Затем вы должны запустить:
cpanm IPC::Run IO::Pty
Это будет работать практически в ] любой современный терминал, поскольку он использует простое перемещение курсора ANSI и коды очистки для постоянной перезаписи нескольких нижних строк экрана.
То же, что и сам rsync
. Обратите внимание, что вам нужно указать - progress
самостоятельно, но вы можете легко отредактировать некоторые аргументы по умолчанию, изменив строку $ h = harness ...
:
my $h = harness [ $RSYNC, '--progress', @ARGV ], 'pty>', \$out;
rsync
] расположение двоичного файла Сценарий пытается автоматически определить расположение двоичного файла rsync
с помощью , который
, который будет работать почти во всех средах. Вы также можете отредактировать строку my $ RSYNC = '...'
, чтобы указать произвольное местоположение, если это необходимо или требуется (важно: замените обратные кавычки (`) на одинарные кавычки (' ) в этом случае.)
Вывод ошибок специально не обрабатывается, но может быть с некоторыми незначительными изменениями в сценарии.
Несмотря на достаточную надежность, очевидно, что это «быстрое» усилие, которое не может учесть все возможные результаты работы невероятно сложной утилиты rsync
. Возможно, вам придется в некоторой степени адаптировать его под свои нужды, что, будем надеяться, достаточно просто: весь вывод поступает в переменную $ out
, которую вы можете обработать в соответствии со своими потребностями.
Как упоминалось выше, я выбрал двухстрочный дисплей без прокрутки , чтобы лучше отображать длинные пути. Однако преобразование вывода в однострочное отображение тривиально. Просто измените строку print ...
в подпрограмме parse ()
на что-то вроде этого:
printf "\e[u\e[0J%-30.30s %s\n", $file, $status;
или, чтобы полностью отказаться от кодов перемещения ANSI:
printf "\r%-30.30s %-40.40s", $file, $status;
STDOUT->flush; # $| = 1 won't help you here
Затем вы Вместо этого вы увидите что-то вроде этого:
src/test.c 142 100% 0.19kB/s 0:00:00 (xfr#28, to-chk=0/30)
Вы могли заметить, что % - 30.30s
- это довольно произвольная ширина printf , и вы были бы правы. Вы можете использовать что-то вроде ответа из этого вопроса , чтобы получить ширину терминала, чтобы вы могли соответственно увеличивать / уменьшать этот размер.
Поиск слова в PDF на самом деле является функцией программы просмотра. Таким образом, каждый зритель по-своему подходит к тому, с чем он будет работать. На практике я обнаружил, что Okular был лучшим выбором среди всех просмотрщиков PDF, которые я тестировал. Насколько мне известно, Mupdf не может обрабатывать слова через дефис.
Обратите внимание, что PDF-файл содержит не исходный текст, а описание, какие глифы куда ставить. Поиск текста в PDF зависит от (1 )PDF, имеющего таблицу (s ), которая описывает, какие глифы соответствуют каким символам Юникода (2 )способ повторной сборки этих переведенных символов в слова (3 )предположения о том, как работало генерирующее приложение, например проставьте глифы в текстовом порядке (, что, например.произойдет ужасный сбой, когда текст двух столбцов -отображается в обоих столбцах одновременно ).
Чтобы учесть переносы, вам нужно реализовать алгоритм, который обнаруживает тире в конце строки (для этого можно использовать разные глифы ), а затем объединяет слово (и берет специальные правила о hypenation во внимание, например для немецкого языкаck
).
Так что да, это можно сделать, но не так просто, и тогда это все равно будет работать только для некоторых языков/скриптов.
Я не знаю, как это сделать внутри MuPDF, но один из способов получить эти строки/совпадения — отфильтровать их с помощьюpdftotext
pdftotext file.pdf - | grep 'meaningless'
По умолчанию pdftotext расставляет строки без переносов.