Bash вывести файл без первой строки
Мне нужно повторно удалить первую строку из огромного текстового файла с помощью скрипта bash.
сейчас я использую sed -i -e "1d" $FILE - но это занимает около минуты, чтобы сделать удаление.
есть ли более эффективный способ сделать это?
- оболочка усекает файл $FILE
- Shell создает новый процесс для tail
- оболочка перенаправляет stdout из
вы можете использовать-i для обновления файла без использования оператора'>'. Следующая команда удалит первую строку из файла и сохранит ее в файл.
для тех, кто находится на SunOS, который не является GNU, следующий код поможет:
нет, это примерно так же эффективно, как вы собираетесь получить. Вы можете написать программу на C, которая может выполнять эту работу немного быстрее (меньше времени запуска и обработки аргументов), но она, вероятно, будет стремиться к той же скорости, что и sed, когда файлы становятся большими (и я предполагаю, что они большие, если это займет минуту).
но ваш вопрос страдает от той же проблемы, что и многие другие, в том, что он предполагает решение. Если бы вы рассказали нам подробно что ты пытаешься делай скорее тогда как, мы можем предложить лучший вариант.
например, если это файл A, который обрабатывает какая-то другая программа B, одним из решений было бы не удалять первую строку, а изменить программу B, чтобы обработать ее по-другому.
предположим, что все ваши программы добавляют к этому файлу A и программа B в настоящее время читает и обрабатывает первую строку перед ее удалением.
вы можете перепроектировать программу B, чтобы она не пыталась удалить первая строка, но поддерживает постоянное (вероятно, файловое) смещение в файл A, чтобы при следующем запуске он мог искать это смещение, обрабатывать строку там и обновлять смещение.
затем, в спокойное время (полночь?), он может выполнить специальную обработку файла A, чтобы удалить все строки, которые в настоящее время обрабатываются, и установить смещение обратно в 0.
Это, безусловно, будет быстрее для программы, чтобы открыть и искать файл, а не открывать и переписывать. Это обсуждение предполагает, что вы иметь контроль над программой, разумеется. Я не знаю, так ли это, но могут быть и другие возможные решения, если вы предоставите дополнительную информацию.
вы можете редактировать файлы на месте: просто используйте perl -i флаг, как это:
это делает первую строку исчезают, как вы спрашиваете. Perl нужно будет прочитать и скопировать весь файл, но он организует для вывода, который будет сохранен под именем исходного файла.
Как сказал Пакс, вы, вероятно, не получите быстрее, чем это. Причина в том, что практически нет файловых систем, которые поддерживают усечение с начала файла, так что это будет O ( n операции), где n размер файла. Что вы можете сделать много быстрее, хотя перезаписать первую строку с тем же количеством байтов (возможно, с пробелами или комментарием), которые могут работать для вас в зависимости от того, что именно вы пытаетесь сделать (что такое это кстати?).
The sponge полезное позволяет избежать необходимости жонглирования временным файлом:
Мне нужно многократно удалять первую строку из огромного текстового файла, используя скрипт bash.
Прямо сейчас я использую sed -i -e "1d" $FILE - но удаление займет около минуты.
Есть ли более эффективный способ сделать это?
-n x : просто напечатайте последние x строки. tail -n 5 выдаст вам последние 5 строк ввода. Знак + инвертирует аргумент и заставляет tail печатать что угодно, кроме первых строк x-1 . tail -n +1 будет печатать весь файл, tail -n +2 все, кроме первой строки и т. д.
GNU tail намного быстрее, чем sed . tail также доступен в BSD, а флаг -n +2 одинаков для обоих инструментов. Проверьте FreeBSD или OS X man-страницы для получения дополнительной информации.
Однако версия BSD может быть намного медленнее, чем sed . Интересно, как им это удалось; tail должен просто читать файл построчно, в то время как sed выполняет довольно сложные операции, включая интерпретацию скрипта, применение регулярных выражений и тому подобное.
Примечание: вы можете испытать желание использовать
но это даст вам пустой файл. Причина в том, что перенаправление ( > ) происходит до того, как оболочка tail будет вызвана:
- Оболочка обрезает файл $FILE
- Shell создает новый процесс для tail
- Оболочка перенаправляет стандартный вывод процесса tail в $FILE
- tail читает из теперь пустого $FILE
Если вы хотите удалить первую строку внутри файла, вы должны использовать:
&& гарантирует, что файл не будет перезаписан при возникновении проблемы.
Вы можете использовать -i для обновления файла без использования оператора «>». Следующая команда удалит первую строку из файла и сохранит ее в файл.
Для тех, кто работает в SunOS, не являющейся GNU, следующий код поможет:
Нет, это примерно так же эффективно, как вы собираетесь получить. Вы могли бы написать программу на C, которая могла бы выполнять работу немного быстрее (меньше времени запуска и обработки аргументов), но она, вероятно, будет стремиться к той же скорости, что и sed, когда файлы становятся большими (и я предполагаю, что они велики, если это займет минуту ).
Но ваш вопрос страдает от той же проблемы, что и многие другие, в том смысле, что он предполагает решение. Если вы расскажете нам подробно что вы пытаетесь сделать, а не как , мы можем предложить лучший вариант.
Например, если это файл A, который обрабатывает какая-то другая программа B, одним из решений было бы не убрать первую строку, а изменить программу B для ее обработки по-другому.
Допустим, все ваши программы добавляют к этому файлу A, и программа B в настоящее время читает и обрабатывает первую строку перед ее удалением.
Вы можете перестроить программу B так, чтобы она не пыталась удалить первую строку, но сохранила постоянное (вероятно, основанное на файлах) смещение в файле A, чтобы при следующем запуске она могла искать это смещение, обрабатывая линия там, и обновить смещение.
Затем в тихое время (полночь?) Он может выполнить специальную обработку файла A, чтобы удалить все обрабатываемые в данный момент строки и установить смещение обратно на 0.
Конечно, для программы будет быстрее открывать и искать файл, чем открывать и перезаписывать. Это обсуждение предполагает, что у вас есть контроль над программой B, конечно. Я не знаю, так ли это, но могут быть и другие возможные решения, если вы предоставите дополнительную информацию.
Вы можете отредактировать файлы на месте: просто используйте флаг Perl -i , например:
Это заставляет первую строку исчезнуть, как вы просите. Perl нужно будет прочитать и скопировать весь файл, но он организует сохранение вывода под именем исходного файла.
Как сказал Пакс, вы, вероятно, не получите быстрее, чем это. Причина в том, что практически нет файловых систем, поддерживающих усечение с начала файла, поэтому это будет операция O ( n ), где n - размер файла. Что вы можете сделать намного быстрее, хотя перезаписать первую строку с таким же количеством байтов (возможно, с пробелами или комментарием), что может работать для вас в зависимости от того, что именно вы пытаетесь сделать (что это делает путь?).
sponge util избавляет от необходимости манипулирования временным файлом:
Мне нужно повторно удалить первую строку из огромного текстового файла с помощью скрипта bash.
сейчас я использую sed -i -e "1d" $FILE - но для удаления требуется около минуты.
есть ли более эффективный способ сделать это?
-n x : просто распечатайте последний x строки. tail -n 5 даст вам последние 5 строк ввода. The + знак вида инвертирует аргумент и делает tail печать ничего, кроме первого x-1 строки. tail -n +1 напечатал бы весь файл, tail -n +2 все, кроме первой строки, и т. д.
GNU tail гораздо быстрее, чем sed . tail также доступно на BSD и -n +2 флаг согласовано в обоих инструментах. Проверьте FreeBSD или OS X man-страницы для более.
версия BSD может быть намного медленнее, чем sed , хотя. Интересно, как им это удалось?--7--> надо просто читать файл построчно, пока sed выполняет довольно сложные операции, связанные с интерпретацией скрипта, применением регулярных выражений и тому подобное.
Примечание: у вас может возникнуть искушение использовать
но это даст вам пустой файл. Причина в том, что перенаправление ( > ) происходит перед tail вызывается оболочкой:
- оболочка усекает файл $FILE
- Shell создает новый процесс для tail
- Shell перенаправляет stdout
вы можете использовать-i для обновления файла без использования оператора'>'. Следующая команда удалит первую строку из файла и сохранит ее в файле.
для тех, кто находится на SunOS, который не является GNU, следующий код поможет:
нет, это примерно так же эффективно, как вы собираетесь получить. Вы можете написать программу на C, которая может выполнять работу немного быстрее (меньше времени запуска и обработки аргументов), но она, вероятно, будет стремиться к той же скорости, что и sed, поскольку файлы становятся большими (и я предполагаю, что они большие, если это займет минуту).
но ваш вопрос страдает от той же проблемы, что и многие другие, поскольку он заранее предполагает решение. Если бы вы рассказали нам подробно что вы пытаетесь делай, а не то как, мы можем предложить лучший вариант.
например, если это файл A, который обрабатывает другая программа B, одним из решений было бы не удалять первую строку, а изменять программу B для ее обработки по-другому.
предположим, что все ваши программы добавляются в этот файл A и программа B в настоящее время читает и обрабатывает первую строку перед ее удалением.
вы можете перепроектировать программу B, чтобы она не пыталась удалить первая строка, но поддерживает постоянное (возможно, файловое) смещение в файл A, чтобы при следующем запуске он мог искать это смещение, обрабатывать строку там и обновлять смещение.
затем, в спокойное время (полночь?), он может выполнить специальную обработку файла A, чтобы удалить все строки, обрабатываемые в настоящее время, и установить смещение обратно в 0.
Это, безусловно, будет быстрее для программы, чтобы открыть и искать файл, а не открывать и переписывать. Это обсуждение предполагает вас контролировать программу Б, конечно. Я не знаю, так ли это, но могут быть другие возможные решения, если вы предоставите дополнительную информацию.
вы can редактировать файлы на месте: просто используйте perl -i флаг, как это:
Это заставляет первую строку исчезнуть, как вы просите. Perl нужно будет прочитать и скопировать весь файл, но он организует для вывода, который будет сохранен под именем исходного файла.
Как сказал Пакс, вы, вероятно, не получите быстрее, чем это. Причина в том, что практически нет файловых систем, поддерживающих усечение с начала файла, поэтому это будет O ( n операции), где n размер файла. Что вы можете сделать много быстрее, хотя перезаписывает первую строку с тем же количеством байтов (возможно, с пробелами или комментарием), которые могут работать для вас в зависимости от того, что вы пытаетесь сделать (что это, кстати?).
Мне нужно многократно удалять первую строку из огромного текстового файла, используя скрипт bash.
Прямо сейчас я использую sed -i -e "1d" $FILE - но удаление занимает около минуты.
Есть ли более эффективный способ сделать это?
@cikatomo: он обозначает встроенное редактирование - он редактирует файл с тем, что вы генерируете. Хвост НАМНОГО МЕДЛЕН, чем сед. хвосту нужно 13,5 с, седу - 0,85 с. Мой файл имеет100 МБ. MacBook Air 2013 с SSD.
-n x : Просто напечатайте последние x строки. tail -n 5 даст вам последние 5 строк ввода. + Знак рода инвертирует аргумент и сделать tail печать ничего , кроме первых x-1 строк. tail -n +1 будет печатать весь файл, tail -n +2 все, кроме первой строки и т. д.
GNU tail намного быстрее чем sed . tail также доступен на BSD, и -n +2 флаг одинаков для обоих инструментов. Проверьте справочные страницы FreeBSD или OS X для получения дополнительной информации.
Версия BSD может быть намного медленнее, чем sed , однако. Интересно, как им это удалось; tail следует просто читать файл построчно, в то время как sed выполняет довольно сложные операции, включая интерпретацию скрипта, применение регулярных выражений и тому подобное.
Примечание: вы можете испытать желание использовать
но это даст вам пустой файл . Причина в том, что redirection ( > ) происходит до того, tail как вызывается оболочкой:
- Файл усеченных оболочек $FILE
- Shell создает новый процесс для tail
- Shell перенаправляет стандартный вывод tail процесса на $FILE
- tail читает из теперь пусто $FILE
Если вы хотите удалить первую строку внутри файла, вы должны использовать:
&& Будет убедиться , что файл не будет перезаписан , когда есть проблема.
@Eddie: user869097 сказал, что это не работает, если одна строка составляет 15 МБ или больше. Пока строки будут короче, tail будут работать файлы любого размера. @Dreampuf - со страницы руководства: -n N means output the last N lines, instead of the last 10; or use +N to output lines starting with the Nth Я собирался согласиться с @JonaChristopherSahnwaldt - tail намного, намного медленнее, чем вариант sed, на порядок. Я тестирую его на файле с 500 000K строк (не более 50 символов в строке). Однако затем я понял, что использую версию tail для FreeBSD (которая по умолчанию поставляется с OS X). Когда я переключился на GNU tail, хвостовой вызов был в 10 раз быстрее, чем вызов sed (и вызов GNU sed тоже). AaronDigulla является правильным здесь, если вы используете GNU.Вы можете использовать -i для обновления файла без использования оператора «>». Следующая команда удалит первую строку из файла и сохранит ее в файл.
Я получаю ошибку: unterminated transform source string это работает каждый раз и действительно должно быть лучшим ответом! Напомним, что Mac требует предоставления суффикса при использовании sed с правками на месте. Так что запустите выше с -i.bak Просто примечание - чтобы удалить несколько строк использовать sed -i '1,2d' filename Эта версия действительно намного более читабельна и универсальна, чем tail -n +2 . Не уверен, почему это не лучший ответ.Для тех, кто работает в SunOS, отличной от GNU, поможет следующий код:
Нет, это примерно так же эффективно, как вы собираетесь получить. Вы могли бы написать программу на C, которая могла бы выполнять работу немного быстрее (меньше времени запуска и обработки аргументов), но она, вероятно, будет стремиться к той же скорости, что и sed, когда файлы становятся большими (и я предполагаю, что они велики, если это займет минуту ).
Но ваш вопрос страдает от той же проблемы, что и многие другие, в том смысле, что он предполагает решение. Если бы вы подробно рассказали нам о том, что вы пытаетесь сделать, а не о том , как , мы можем предложить лучший вариант.
Например, если это файл A, который обрабатывает какая-то другая программа B, одним из решений было бы не убрать первую строку, а изменить программу B для ее обработки по-другому.
Допустим, все ваши программы добавляют к этому файлу A, и программа B в настоящее время читает и обрабатывает первую строку перед ее удалением.
Вы могли бы перепроектировать программу B так, чтобы она не пыталась удалить первую строку, но сохранила постоянное (вероятно, основанное на файле) смещение в файле A, чтобы при следующем запуске она могла искать это смещение, обрабатывая линия там, и обновить смещение.
Затем в тихое время (полночь?) Он может выполнить специальную обработку файла A, чтобы удалить все обрабатываемые в данный момент строки и установить смещение обратно на 0.
Конечно, для программы будет быстрее открывать и искать файл, чем открывать и перезаписывать. Это обсуждение предполагает, что у вас есть контроль над программой B, конечно. Я не знаю, так ли это, но могут быть и другие возможные решения, если вы предоставите дополнительную информацию.
Читайте также: