PF=(opt/N*.properties)
cp "${PF[@]}" /opt/backup
Пропустите цикл for и скопируйте все файлы в одной команде, таким образом глобус создает массив, а оболочка может расширять элементы в массиве в способ, показанный выше.
Если вы все еще хотите использовать цикл for, вы можете пропустить объявление переменной и просто выполнить для myfile в opt / N * .properties; делать ...
Однострочная команда awk
:
awk -v P=-1 '$2<104 {if ($1>P+1)N=$1;P=$1;print $1,$2>"file"N".tmp"}'
Дает результат (, если вы не возражаете против имени файла)
==> file1.tmp <==
1 102.0184
2 100.2430
3 103.9029
4 102.7495
5 102.8825
==> file7.tmp <==
7 103.0479
8 101.2433
==> file10.tmp <==
10 101.5879
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
— номера начала/конца строки диапазона. Их состояния будут информировать нас для принятия надлежащих решений.
Ниже представлена awk
программа. Вы можете поиграть со столбцом и порогом, указанным в аргументах :
awk -v column=2 -v threshold=104 '
function save() { if (lines != "") print lines >"file_" first "-" last ".txt" }
! ($column < threshold) {
save()
first = last = lines = ""
next
}
{
if (first == "") first = $1
last = $1
lines = lines $1 OFS $column ORS
}
END { save() }
'
Обратите внимание, что непрерывные строки сохраняются в памяти до тех пор, пока они не будут сохранены. Если у вас есть сотни миллионов непрерывных строк, это решение следует адаптировать (, сохраняя каждую строку во временном файле, а затем переименовывая его, когда встречается последняя строка непрерывного блока ).