awk '{$0 = $2 < 104 ? NR : RS}1' inputfile |
sed -Ee '
$aq
/./,/^$/!d;/./H;$ba;/^$/ba;d;:a
g;s/.//;s/\n.*\n|\n/,/;x;s/.*//;x
s/(.*),(.*)/&w file_\1_\2.tmp/
/,/!s/.*/&w file_&.tmp/
' | ed -s inputfile -
Здесь мы используем инструменты awk/sed/ed
. Awk
сначала генерирует номера строк для
все те строки, которые меньше 104. Для других он печатает пустую строку.
Затем приходит Sed
и просматривает диапазоны строк от непустой строки до следующей пустой строки. И сохраняет номера строк в трюме. Теперь можно найти два типа диапазонов: n,m или обычный n. Используя их, мы создаем набор команд ed
, который преобразует такие диапазоны в: n,mw file_n_m.tmp и file_n.tmp соответственно. Затем ed быстро обрабатывает входной файл, используя этот динамически сгенерированный ed-скрипт, чтобы поместить строки в свои файлы .tmp.
Вот один из способов выполнить вашу задачу с помощью Perl
:
perl -lane '
BEGIN { $fmt = sprintf q[%s%%s\n%s], (chr 39)x2; }
if ( $F[1] < 104 ) {
push @A, "@F[0,1]";
if ( eof ) {
my $f = join $", q<printf>, $fmt, map(qq[\"$_\"], @A), q[>], (( ! defined $a ) ? qq[file_${.}.tmp] : qq[file_${a}_${.}.tmp]);
system("$f");
} else { $a //= $.; }
} else {
next if ! defined $a;
$b //= $.-1;
my $f = join $", q<printf>, $fmt, map(qq[\"$_\"], @A), q[>], (( $a == $b ) ? qq[file_$b.tmp] : qq[file_${a}_$b.tmp]);
system("$f");
($a, $b, @A) = (undef)x2;
}
' yourfile
Учитывая ввод, создаются следующие 3 файла: file_1_5.tmp file_7_8.tmp file_10.tmp
с содержимым
% больше file_1_5.tmp file_7_8.tmp file_10.tmp
::::::::::::::
file_1_5.tmp
::::::::::::::
1 102.0184
2 100.2430
3 103.9029
4 102.7495
5 102.8825
::::::::::::::
file_7_8.tmp
::::::::::::::
7 103.0479
8 101.2433
::::::::::::::
file_10.tmp
::::::::::::::
10 101.5879
Сначала основная идея верхнего уровня: мы следим за тем, не отстает ли второе поле от числового 104.В сценарии, когда это происходит, означает, что нам нужно напечатать предыдущий диапазон. Просто имейте в виду, что для диапазонов unilength имя файла изменяется соответствующим образом, чтобы отразить это.
Другой случай, когда мы находимся в процессе накопления текущего диапазона ($F[1] < 104), просто имейте в виду, что при этом, если мы нажмем eof
, нам нужно распечатать диапазон сейчас.
P.S.: Команда system
создается динамически с использованием динамически создаваемого формата, ее данные представляют собой первое и второе поля, и, наконец, имя файла .tmp создается в соответствии с диапазоном.
$a
и $b
— номера начала/конца строки диапазона. Их состояния будут информировать нас для принятия надлежащих решений.
Недавно столкнулся с такой же проблемой. И настоящая проблема заключается в том, как сообщить почтмейстеру его реальное местоположение файла конфигурации. Все, что нам нужно сделать, это добавить -c config_file <configuration/filename/location>
в качестве параметра командной строки в процесс postgres. И проблема :в том, как это сделать...?
Давным-давно, в далекой-далекой галактике, у нас были сценарии инициализации System V, и мы могли настраивать параметры командной строки в определенном файле, расположенном где-то там; /etc/sysconfig каталог. Но теперь у нас есть systemd -надежный, продвинутый и... трудно настраиваемый механизм, позволяющий делать все и даже больше. Таким образом, единственный способ разделить файлы конфигурации и файлы данных — настроить систему инициализации postgresql systemd. Как этого добиться? Вот что я сделал:
Прежде всего я переместил файлы конфигурации :postgresql.conf, pg _hba.conf ang pg _ident.conf во внешний каталог, скажем:/var/lib/pgsql/config
Я настроил новое расположение вышеуказанных файлов в postgresql.conf:
hba_file = '/var/lib/pgsql/config/pg_hba.conf'
ident_file = '/var/lib/pgsql/config/pg_ident.conf'
Я отредактировал systemd postgresql.service, переопределив существующую (конфигурацию системы ):
systemctl edit postgresql.service
Это вызывает создание нового пустого файла службы systemd :/etc/systemd/system/postgresql.service.d/override.conf и открывает его в редакторе $EDITOR.
Я положил туда:
[Service]
ExecStart=
ExecStart=/usr/bin/pg_ctl start -D ${PGDATA} -s -o "-p ${PGPORT} -c config_file=/var/lib/pgsql/config/postgresql.conf" -w -t 300
Как мы видим, -я добавил строку :" -c config _file /var/lib/pgsql/config/postgresql.conf" в аргумент -o. Еще один интересный момент — пустая :директива «ExecStart». Несмотря на то, что это называется :"overriding", мы должны прежде всего обнулить эту директиву, иначе мы получим ошибку :"postgresql.service имеет более одной настройки ExecStart=...".
Перезапущен сервис :systemctl restart postgresql
И мне понравился Postgresql с файлами данных в $PGDATA и файлами конфигурации везде:
/usr/bin/postgres -D /var/lib/pgsql/data -p 5432 -c config_file=/var/lib/pgsql/config/postgresql.conf
Я сделал это с CentOS 7 и RHEL7,но надеюсь, что он должен работать в любой ОС на основе systemd.
Надеюсь, эта история будет кому-то полезна.
С уважением.