Я верю uid
и gid
параметры в файле конфигурации сервера для разделения полномочия.
auth users
параметр в Вашей конфигурации явно отклоняет все другие имена пользователей, чем"backuppc
".
Так, Вам нужен "backuppc" в rsyncd.secrets на "Host1", а также на командной строке на "Host2".
Попытайтесь удалить auth users
оператор от /etc/rsyncd.conf
, или перепроверка, что Вы - действительно пользователь backuppc
на Host2 (не "пользователь" или "имя пользователя", как в примере "От host2":).
При поиске и устранении неисправностей также попытайтесь добавить strict modes = false
к Вашему rsyncd файлу конфигурации.
Вот решение, которое может сработать:
seq 1 $(((lines=$(wc -l </tmp/file))/16+1)) $lines |
sed 'N;s|\(.*\)\(\n\)\(.*\)|\1d;\1,\3w /tmp/uptoline\3\2\3|;P;$d;D' |
sed -ne :nl -ne '/\n$/!{N;bnl}' -nf - /tmp/file
Оно работает, позволяя первому sed
написать сценарий второго sed
. Второй sed
первый собирает все входные строки до тех пор, пока не встретит пустую строку. Затем он записывает все выходные строки в файл. Первый sed
записывает скрипт для второго, указывая ему, куда записывать выходные данные. В моем тестовом случае этот скрипт выглядел следующим образом:
1d;1,377w /tmp/uptoline377
377d;377,753w /tmp/uptoline753
753d;753,1129w /tmp/uptoline1129
1129d;1129,1505w /tmp/uptoline1505
1505d;1505,1881w /tmp/uptoline1881
1881d;1881,2257w /tmp/uptoline2257
2257d;2257,2633w /tmp/uptoline2633
2633d;2633,3009w /tmp/uptoline3009
3009d;3009,3385w /tmp/uptoline3385
3385d;3385,3761w /tmp/uptoline3761
3761d;3761,4137w /tmp/uptoline4137
4137d;4137,4513w /tmp/uptoline4513
4513d;4513,4889w /tmp/uptoline4889
4889d;4889,5265w /tmp/uptoline5265
5265d;5265,5641w /tmp/uptoline5641
Я тестировал его следующим образом:
printf '%s\nand\nmore\nlines\nhere\n\n' $(seq 1000) >/tmp/file
Это дало мне файл в 6000 строк, который выглядел следующим образом:
<iteration#>
and
more
lines
here
#blank
...повторялся 1000 раз.
После выполнения скрипта выше:
set -- /tmp/uptoline*
echo $# total splitfiles
for splitfile do
echo $splitfile
wc -l <$splitfile
tail -n6 $splitfile
done
15 total splitfiles
/tmp/uptoline1129
378
188
and
more
lines
here
/tmp/uptoline1505
372
250
and
more
lines
here
/tmp/uptoline1881
378
313
and
more
lines
here
/tmp/uptoline2257
378
376
and
more
lines
here
/tmp/uptoline2633
372
438
and
more
lines
here
/tmp/uptoline3009
378
501
and
more
lines
here
/tmp/uptoline3385
378
564
and
more
lines
here
/tmp/uptoline3761
372
626
and
more
lines
here
/tmp/uptoline377
372
62
and
more
lines
here
/tmp/uptoline4137
378
689
and
more
lines
here
/tmp/uptoline4513
378
752
and
more
lines
here
/tmp/uptoline4889
372
814
and
more
lines
here
/tmp/uptoline5265
378
877
and
more
lines
here
/tmp/uptoline5641
378
940
and
more
lines
here
/tmp/uptoline753
378
125
and
more
lines
here
Используя предложение csplit
:
$ csplit file.txt <num lines> "{repetitions}"
Скажем, у меня есть файл с 1000 строк в нем.
$ seq 1000 > file.txt
$ csplit file.txt 100 "{8}"
288
400
400
400
400
400
400
400
400
405
приводит к тому, что файлы выглядят так:
$ wc -l xx*
99 xx00
100 xx01
100 xx02
100 xx03
100 xx04
100 xx05
100 xx06
100 xx07
100 xx08
101 xx09
1 xx10
1001 total
Вы можете обойти статическое ограничение на указание количества повторений, предварительно вычислив числа, основанные на количестве строк в вашем конкретном файле.
$ lines=100
$ echo $lines
100
$ rep=$(( ($(wc -l file.txt | cut -d" " -f1) / $lines) -2 ))
$ echo $rep
8
$ csplit file.txt 100 "{$rep}"
288
400
400
400
400
400
400
400
400
405
Если же Вы хотите просто разбить файл на пустые строки, содержащиеся в файле, Вы можете использовать эту версию split
:
$ csplit file2.txt '/^$/' "{*}"
Скажем, я добавил 4 пустые строки в file.txt
выше, и создал файл file2.txt
. Вы видите, что они были добавлены вручную так:
$ grep -A1 -B1 "^$" file2.txt
20
21
--
72
73
--
112
113
--
178
179
Выше видно, что я добавил их между соответствующими номерами в моем файле-примере. Теперь, когда я запускаю команду csplit
:
$ csplit file2.txt '/^$/' "{*}"
51
157
134
265
3290
Вы видите, что теперь у меня есть 4 файла, которые были разбиты на пустую строку:
$ grep -A1 -B1 '^$' xx0*
xx01:
xx01-21
--
xx02:
xx02-73
--
xx03:
xx03-113
--
xx04:
xx04-179
Если вас не волнуют приказы записей, вы можете это сделать:
gawk -vRS= '{printf "%s", $0 RT > "file.out." (NR-1)%15}' file.in
Иначе сначала нужно получить количество записей, чтобы узнать, сколько их поместить в каждый выходной файл:
gawk -vRS= -v "n=$(gawk -vRS= 'END {print NR}' file.in)" '
{printf "%s", $0 RT > "file.out." int((NR-1)*15/n)}' file.in
Попробуйте awk
awk 'BEGIN{RS="\n\n"}{print $0 > FILENAME"."FNR}' big_db.msg
Если вы ищете сплит только в конце строки, то это можно сделать с помощью опции -l
для сплита
.
Если вы хотите разделить строку на пустую ( \n\n
), вот как я это сделаю в ksh. Я не тестировал, и, наверное, это не идеально, но что-то в этой строке сработало бы:
filenum=0
counter=0
limit=580000
while read LINE
do
counter=counter+1
if (( counter >= limit ))
then
if [[ $LINE == "" ]]
then
filenum=filenum+1
counter=0
fi
fi
echo $LINE >>big_db$filenum.msg
done <big_db.msg
Если вам не важен порядок записей, но вам нужно получить определенное количество выходных файлов, Ответ Стефана - это то, как я бы идти. Но я чувствую, что вам может быть интересно указать размер, который не должен превышать каждый выходной файл. Это на самом деле упрощает задачу, поскольку вы можете читать свой входной файл и собирать записи, пока не достигнете этого размера, а затем запустить новый выходной файл. Если это сработает для вас, большинство языков программирования могут справиться с вашей задачей с помощью короткого сценария. Вот реализация awk:
BEGIN {
RS = "\n\n"
ORS = "\n\n"
maxlen = (maxlen == 0 ? 500000 : maxlen)
oi = 1
}
{
reclen = length($0) + 2
if (n + reclen > maxlen) {
oi++
n = 0
}
n += reclen
print $0 > FILENAME"."oi
}
Поместите это в файл, скажем program.awk
, и запустите его с помощью awk -v maxlen = 10000 -f program.awk big_db.msg
где значение maxlen
- это максимальное количество байтов, которое вы хотите в одном файле. По умолчанию будет использоваться 500 КБ.
Если вы хотите получить определенное количество файлов, возможно, самый простой способ - просто разделить размер входного файла на количество файлов, которое вы хотите, а затем добавить немного к этому числу, чтобы получить maxlen
. Например, чтобы получить 15 файлов из ваших 8726593 байтов, разделите на 15, чтобы получить 581773, и добавьте несколько, так что, возможно, вы получите maxlen = 590000
или maxlen = 600000
. Если вы хотите, чтобы это повторялось, можно было бы настроить программу для этого.
split -n l/100 input_file prefix_name
Это разделит большой файл с именем input_file
на 100 файлов с именем prefix_nameXX
без обрезки строк.