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


9

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

(Мене особливо не турбує втрата інформації. Я хочу скоротити файл, щоб я міг перевірити програмне забезпечення на цьому і не чекати багато годин на відповідь. Більш короткий файл дозволить мені це зробити.)


1
Ви маєте на увазі, що хочете усікати файл, чи ви хочете видалити інформацію з усього файлу?
AFH

1
Знайшов це на SO; 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на місці.


5
Це, ймовірно, не призведе до читабельного XML-файлу, коли буде зроблено.
Джо

3
@Joe - ОП не запитував файл для читання (а також не сказав, що це може бути нечитабельним). Вони сказали, що їх не хвилює втрата інформації. Я очікував би нового питання від ОП про те, як виправити вказаний файл.
KevinDTimm

3
Я знаю достатньо xml, щоб виправити це, я написав DTD для формату!
adrianmcmenamin

37

Для обрізання файлу в 1 гігабайт скористайтеся truncateкомандою:

truncate -s 1G file.xml

Результатом усічення, ймовірно, не буде дійсний XML-файл, але я вважаю, що ви це розумієте.

Документація на версію GNU truncateє тут, а документація для версії BSD - тут


14

Де можливо, я використовував би truncateкоманду, як у відповіді John1024. Однак це не стандартна команда 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


0

Врешті-решт я просто sedвидобув довільну кількість рядків:

sed -n 1,1000000p infile.xml>outfile.xml

1
Якщо я відкинув, чи відповідає це питання чи ні, це сканує весь файл, я вважаю, тому його набагато ефективніше використовувати sed 1000000q(і трохи компактніше, візуально кажучи).
B Layer
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.