Поведение, которое Вы описываете и природа файла, заставляет меня подозревать, что это - редкий файл. Редкие файлы являются примитивным методом сжатия, в котором большие последовательности пустых байтов в файле не хранятся на диске. Вот пример, где я создаю редкий файл:
$ echo a | dd seek=999999999 >sparse
0+1 records in
0+1 records out
2 bytes (2 B) copied, 6.614e-05 s, 30.2 kB/s
$ ls -l a
-rw-r--r-- 1 gilles gilles 511999999490 Apr 30 00:03 sparse
$ du sparse
16 sparse
Файл sparse
содержит 511 999 999 490 байтов (999 999 999 блоков 512 байтов, весь нуль, плюс два байта a
сопровождаемый новой строкой). Все же общее дисковое пространство, используемое файлом, составляет 16 КБ (4 КБ для заключительного блока и 3 других блоков, содержащих только метаданные, связанные с местоположением других блоков — все они отсутствуют).
Если honey.img
образ диска, который был создан достаточно тщательно, это может быть редко, где диск имел неиспользуемое место.
Когда Вы читаете из файла, нет ничего для маркировки его как редкий. Итак, если honey.img
большой образ диска, dd
может читать гигабайт на гигабайт, содержащий только пустые байты.
Выполнение ls -l
и du
на файле (или, на OSX, ls -ls
) показал бы число байтов и количество блоков, используемых для устройства хранения данных. Если байты не поместились бы в количество блоков, файл редок. Как я пишу, Вы не отправили четкие данные, которые могли подтвердить или ослабить это.
Один инструмент, который я знаю на OSX, который может скопировать редкие файлы эффективно, является rsync. Однако то, что Вы делаете здесь, не копирует файл от одной файловой системы до другого, но копирует поток байтов (который, оказывается, прибывает из файла) на диск. Можно только сделать это, если данные на самом деле соответствуют на целевом диске.
Я предполагаю, что этот вопрос связан с тем, корректным?
В этом случае, не был бы, заменяя '^' с новой строкой быть большим количеством ценности Ваш в то время как? В следующем я предполагаю, что Вы имеете в виду '^ ', байт NUL ASCII:
$ sed 's/\o000/\n/g' abc.txt | head -n 2
abc.tar
xxx.tar
Таким образом, Вам нужно
sed 's/\o000/\n/g' abc.txt | head -n 2 > newfile.txt
Объяснение
Это заменяет новой строкой (\n
) для каждого байта NUL (\o000
) \o
часть означает, что то, что следует, является байтом в восьмеричной нотации. Вывод затем передается по каналу к head -n 2
который извлекает первые две строки; и получающиеся строки перенаправляются (>
) в файл newfile.txt
.
Если для Вас важно, чтобы имена файлов были разделены '^ ', однако, можно использовать это:
perl -nl000 -e '
$num_lines =2 ;
push @a,(split /\000/)[0..$num_lines-1];
print $_ for @a' abc.txt > newfile.txt
Замените значение $num_lines
выше по мере необходимости для захвата первого $num_lines
строки из файла.
Объяснение
-n
переключатель говорит perl
выполнять код каждой строки входного файла-l000
последовательность говорит perl
установить выходной разделитель записей (символ, распечатанный после каждой строки) к байту NUL (000
).-e
переключатель говорит perl
то, что строка, которая следует, является кодом для выполнения.split
функционируйте разделяет каждую входную строку с байтом NUL как разделитель, берет первое $num_lines
([0..$num_lines-1]
) результаты и помещают их в массив @a
. Заметьте, что "текущая входная часть" строки нигде не указана в вызове функции. Это использует то, что скалярная переменная по умолчанию в Perl ($_
) параметр по умолчанию split
функция (среди других), когда никакой аргумент не предоставляется.foreach
цикл печатает каждый элемент в @a
(снова отметьте как $_
итератор по умолчанию для foreach
цикл). Так как мы установили выходной разделитель записей на восьмеричный 000
, мы разделили результаты байтом NUL как прежде.Это:
awk -F"@" '{print $1"@"$2"@"}' abc.txt > newfile.txt
достаточно хороший для Вас?
@
персонажи.
– Gilles 'SO- stop being evil'
06.08.2013, 04:22
(.*)(.*)
? Также, почему использование cat
? Можно сделать sed -r 'pattern_here' file
непосредственно. Наконец, этот код, кажется, предполагает, что входной файл только имеет 3 имен файлов, из которых Вы извлекаете первый только.
– Joseph R.
05.08.2013, 20:37
.*
должен соответствовать на чем-либо, идея состоит в том, чтобы разделить контент использования файла @
как разделитель. И почему бы не использовать cat
- это - столь же жизнеспособный метод как любой другой.
– Alexej Magura
05.08.2013, 21:14
(.*)(.*)
не приведет ни к какому другому результату (.*)
почему Вы повторяли его? Что касается, почему бы не использовать cat
, это не о функциональности, это о прикреплении на ненужной сложности. Это не что cat
был сделан для так или иначе.
– Joseph R.
05.08.2013, 21:17
(.*)
и так, чтобы может быть то, почему существует дополнительный. При необходимости не стесняйтесь редактировать вышеупомянутое.
– Alexej Magura
05.08.2013, 21:19
Вот пример с помощью Perl:
$ perl -ne '@F = split(/@/,$_); print "$F[1]\@$F[2]@";' abc.txt > newfile.txt
Вышеупомянутое делает следующее:
@F = split(/@/,$_)
- разделяет содержание файла abc.txt
строка за один раз на основе символа @
и хранит получающиеся блоки в массиве (@F
).print "$F[1]\@$F[2]@"
- печатает первые 2 столбца, (1 и 2), от массива @F
и вставляет знак at sign (@
) промежуточный каждый столбец.Awk может использовать любой символ в качестве разделителя записей (с новой строкой как значение по умолчанию), за исключением того, что некоторые реализации не поддерживают пустой байт как разделитель. Простофиля (GNU awk), значение по умолчанию awk на самых невстроенных установках Linux, поддержки аннулируют.
gawk -v RS='\0' -v ORS='\0' 'NR <= 2 {print}'
Это может быть сокращено к gawk -v RS='\0' -v ORS='\0' 'NR <= 2'
начиная с печати записи действие по умолчанию.
Для большого файла необходимо выйти после второй строки.
gawk -v RS='\0' -v ORS='\0' 'NR==3 {exit} {print}'
С другой стороны, можно использовать head
. Нет никакой опции использовать пустой байт вместо новой строки как разделитель записей, но можно подкачать эти два символа, звонить head
, и затем подкачка назад.
tr '\0\n' '\n\0' | head -n 2 | tr '\0\n' '\n\0'