Как я могу сократить файл из командной строки?

9

У меня есть xml-файл объемом 150 ГБ, который я хотел бы сократить (т.е. усечь) до 1 ГБ - есть ли простая (bash или аналогичная) команда, которую я могу использовать, или мне нужно идти программным путем (редактируя его в vi или emacs) кошмар даже на больших железных системах)?

(Я не особенно обеспокоен потерей информации, мне нужен более короткий файл, чтобы я мог протестировать часть программного обеспечения на этом и не ждать много часов ответа, более короткий файл позволит мне это сделать.)

adrianmcmenamin
источник
1
Вы имеете в виду, что хотите обрезать файл или хотите удалить информацию из всего файла?
AFH
1
Нашел это на ТАК; stackoverflow.com/a/15934078/2800918 .
CAB
2
Поскольку это файл XML, который, как я предполагаю, содержит последовательность с большим количеством элементов, вы также можете использовать язык преобразования XML, такой как XQuery, для фильтрации определенного количества этих элементов, что будет иметь преимущество для вывода правильного XML ( Пример )
Аарон
4
Должен ли файл по-прежнему иметь действительный XML-код?
Джо
1
нет, я только что исправил это так
adrianmcmenamin

Ответы:

15

Предполагая, что вы хотите обрезать и извлечь первые 1 ГБ файла размером 150 ГБ:

С head:

head -c 1G infile > outfile

Обратите внимание, что Gсуффикс можно заменить, GBчтобы выровнять по 1000 вместо 1024.

Или с dd:

dd if=infile of=outfile bs=1M count=1024

Или, как в ответе Wumpus Q. Wumbley, ddможет усечь на месте.

multithr3at3d
источник
5
Это, скорее всего, не приведет к прочтению XML-файла, когда это будет сделано.
Джо
3
@Joe - OP не запрашивал читаемый файл (и при этом они не говорили, что он может быть нечитаемым). Они сказали, что не заботятся о потере информации. Я ожидаю новый вопрос от OP о том, как исправить указанный файл.
KevinDTimm
3
Я знаю достаточно XML, чтобы исправить это, я написал DTD для формата!
adrianmcmenamin
37

Чтобы обрезать файл до 1 гигабайта, используйте truncateкоманду:

truncate -s 1G file.xml

Результат усечения, скорее всего, не будет правильным XML-файлом, но я понимаю, что вы это понимаете.

Документация для версии ГНУ truncateявляется здесь и документация для версии BSD является здесь

John1024
источник
14

Где возможно, я бы использовал truncateкоманду, как в ответе Джона 1024. Однако это не стандартная команда unix, так что вы можете однажды оказаться не в состоянии ее использовать. В этом случае также ddможно выполнить усечение на месте.

ddПоведение по умолчанию - обрезать выходной файл в точке, где копирование заканчивается, так что вы просто даете ему входной файл 0 длины и говорите ему начинать запись в нужной точке усечения:

dd if=/dev/null of=filename bs=1048576 seek=1024

(Это не то же самое, что копирование и усечение ddв ответе multithr3at3d.)

Обратите внимание, что я использовал 1048576 и 1024, потому что 1048576 * 1024 - желаемый размер. Я избегал бс = 1м , потому что это «портативность» ответ, и классический ddзнает только суффиксы k, bи w.


источник
2
Для общего решения вы, вероятно, должны заметить, что bsчисло, умноженное на seekчисло, - это количество байтов, которое нужно сохранить. Любые два числа, которые удовлетворяют этому ограничению, должны работать; например, bs=1073741824 seek=1или bs=1 seek=1073741824. Или, так как по bsумолчанию 512, seek=2097152один также должен работать. И вы можете использовать обозначение , как 1M, 1K, 1Gи 2M.
G-Man говорит: «Восстановите Монику»
1

Я не совсем уверен, что вы спрашиваете. Вы просто хотите избавиться от остальных 149 ГБ или пытаетесь сжать 150 ГБ в 1 ГБ? Несмотря на это, это может быть полезным методом для достижения этой цели.

Команда splitможет разбить любой файл на несколько частей. Видеть человека разделились . Вы можете указать размер фрагментов файла, на которые хотите разбить его, с помощью -bопции. Например:

$ split -b 1 ГБ myfile.xml

Без каких-либо других параметров это должно создать несколько файлов в текущем каталоге, начиная с буквы x. Если вы хотите настроить имена разделенных файлов, обратитесь к справочной странице.

Для повторной сборки файла просто используйте cat * > re-assembled.xml.

Пример:

[kent_x86.py@c7 split-test]$ ls -l opendocman*
-rw-rw-r--.  1 kent_x86.py kent_x86.py 2082602 Mar 31  2017 opendocman-1.3.5.tar.gz

[kent_x86.py@c7 split-test]$ split -b 100K opendocman-1.3.5.tar.gz 
[kent_x86.py@c7 split-test]$ ls
opendocman-1.3.5.tar.gz  xaa  xab  xac  xad  xae  xaf  xag  xah  xai  xaj  xak  xal  xam  xan  xao  xap  xaq  xar  xas  xat  xau
[kent_x86.py@c7 split-test]$ ll
total 4072
-rw-rw-r--. 1 kent_x86.py kent_x86.py 2082602 Jan  5 11:06 opendocman-1.3.5.tar.gz
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xaa
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xab
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xac
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xad
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xae
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xaf
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xag
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xah
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xai
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xaj
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xak
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xal
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xam
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xan
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xao
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xap
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xaq
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xar
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xas
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xat
-rw-rw-r--. 1 kent_x86.py kent_x86.py   34602 Jan  5 11:06 xau
[kent_x86.py@c7 split-test]$ cat xa* > opendoc-reassembled.tar.gz
[kent_x86.py@c7 split-test]$ ls -l opendoc-reassembled*
-rw-rw-r--. 1 kent_x86.py kent_x86.py 2082602 Jan  5 11:07 opendoc-reassembled.tar.gz
Kentgrav
источник
0

Вы можете использовать splitкоманду.

split -C 1G <filename>

Для более подробной информации взгляните на этот ответ stackoverflow

ventsyv
источник
0

В конце я просто использовал sedдля извлечения произвольное количество строк:

sed -n 1,1000000p infile.xml>outfile.xml
adrianmcmenamin
источник
1
Оставляя в стороне вопрос, отвечает ли это на вопрос или нет, я считаю, что он будет сканировать весь файл, поэтому его гораздо эффективнее использовать sed 1000000q(и немного компактнее, визуально говоря).
B Layer