Розділіть файл за рядком і контролюйте отримане розширення файлів


28

Існує стандартна команда для розбиття файлів - split.

Наприклад, якщо я хочу розділити файл слів на кілька фрагментів 10000 рядків, я можу використовувати:

split -dl 10000 words wrd

і він створив би кілька файлів форми wrd.01, wrd.02 тощо.

Але я хочу мати певне розширення для цих файлів - наприклад, я хочу отримати файли wtd.01.txt, wrd.02.txt.

Чи є спосіб це зробити?

Відповіді:


12

Не з split, але ви можете легко перейменувати їх згодом, або це можна зробити awk:

awk '{filename = "wrd." int((NR-1)/10000) ".txt"; print >> filename}' inputfile

Виглядає добре - але не працює. У вашій формі скарги на "вираз для перенаправлення` >> 'має нульове значення рядка ", а якщо" файл "" змінено "на" ім'я файлу ", виводить файли форми wrd. {Номер файлу}. {Рядок номер} .txt (їх досить багато :)
Рогач

@Rogach Вибачте, я не тестував його, тому забув awk не робить цілого поділу. Я перевірив цю.
Кевін

49

Тоді це було недоступно, але в останніх версіях ( ≥ 8.16) gnu splitоднієї з них можна використовувати --additional-suffixперемикач, щоб контролювати отримане розширення. Від man split:

--additional-suffix=SUFFIX
              append an additional SUFFIX to file names.

тому при використанні цього параметра:

split -dl 10000 --additional-suffix=.txt words wrd

отримані шматочки автоматично закінчуються .txt:

wrd00.txt
wrd01.txt
.........

3
Не працює над mac
ericgu

2
Я люблю твій сарказм. Я unix n00b зі світу Apple. Я використовую OS X Yosemite, і я просто не хотів, щоб інші руйнувалися і горіли, як я. Я тестував і перевіряв у документах, і у нас немає цього параметра. Я, можливо, щось пропустив. developer.apple.com/library/mac/documentation/Darwin/Reference/…
ericgu

5
@swiftshokunin - моя відповідь стосується gnu splitчастини gnu coreutils. Він також доступний в OSX, якщо ви встановлюєте coreutilsчерез, homebrewале зауважте, що за замовчуванням на OSX, gnuутиліти мають попередньо вказане gім'я (наприклад, gstatзамість stat), тому ви викликаєте його як gsplit(або змінюєте PATH відповідно до посібника тут, якщо ви хочете використовувати його як splitнад OSX split). HTH.
don_crissti

1
Гарна відповідь. в OS X використовуйте gsplitдля роботи числових суфіксів (-d).
Brent Faust

1
уау, я поняття не мав, що існує gsplit - це, мабуть, з Coreutils, згаданий вище, і він має - додатковий суфікс. Дякуємо всім, хто коментує це рішення :)
Łukasz Rysiak

13

Такі завдання найкраще справляються із оболонкою. Скористайтеся розділенням, а потім напишіть простий цикл для перейменування файлів. Напр

for file in wrd.*
do
    mv "$file" "$file.txt"
done

перейменовує ваші файли wrd.01, wrd.02 тощо, щоб вони мали розширення .txt.


Це цілком очевидно, але це порушило б стислість баш сценарію.
Рогач

1
Філософія Unix полягає у наданні вам набору простих інструментів, які ви потім комбінуєте для виконання роботи. "Лаконічність баш-сценарію" не була заявленою вимогою у вашому запитанні.
Кайл Джонс

7
PS: split+mvкомбо більше, ніж у 6 разів швидше, ніж awk(приблизно 3s проти 18s ) для 10-мільйонного вхідного файлу рядка (75 Мб) ... текст у кожному рядку був власним номером рядка ... Дякую за перезапис the "очевидний" :)
Peter.O

3
PPS: Я щойно перевіряв це трохи далі. Різниця в швидкості пов'язана з кількістю створених файлів проти кількості форматування та арифметичних обчислень, які awk робить для кожного рядка незалежно від кількості вихідних файлів ... Використовуючи той самий вхідний файл, що і вищенаведений приклад: Коли є У 100 разів менше файлів, split + mvце в 75 разів швидше, ніж awk: Коли файлів у 100 разів більше , split + mvце в 1,5 рази швидше, ніж awk. Отже, для мене цей split + mvметод виграє, руки вниз. Це як консис (імовірно більше), і швидше, ніж awk.
Пітер.О

1
якщо ви стурбовані тим, що це довга 5 рядків, спробуйте це замість цього: for file in wrd.*; do mv "$file" "$file.txt"; done:)
Тоні,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.