У меня есть файл temp.txt, который я хочу отсортировать с помощью sort
команды в bash.
Я хочу, чтобы отсортированные результаты заменили исходный файл.
Например, это не работает (у меня пустой файл):
sortx temp.txt > temp.txt
Можно ли это сделать одной строкой, не прибегая к копированию во временные файлы?
РЕДАКТИРОВАТЬ: -o
вариант очень крутой для sort
. Я использовал sort
в своем вопросе в качестве примера. У меня такая же проблема с другими командами:
uniq temp.txt > temp.txt.
Есть ли лучшее общее решение?
Ответы:
источник
sort --inplace *.txt
? Это было бы безумно крутоfind . -name \*.txt -exec sort {} -o {} \;
sort
Должен видеть все входные данные, прежде чем он может начать вывод. По этой причинеsort
программа может легко предложить возможность изменить файл на месте:В частности, в документации GNU
sort
говорится:В документации BSD
sort
сказано:Такие команды, как,
uniq
могут начать запись вывода до того, как закончат чтение ввода. Эти команды обычно не поддерживают редактирование на месте (и им было бы сложнее поддерживать эту функцию).Обычно это обходится с временным файлом, или, если вы абсолютно не хотите иметь промежуточный файл, вы можете использовать буфер для сохранения полного результата перед его записью. Например, с
perl
:Здесь часть perl считывает полный вывод из
uniq
переменной,$_
а затем перезаписывает исходный файл этими данными. Вы можете сделать то же самое на любом языке сценариев по вашему выбору, возможно, даже в Bash. Но учтите, что для хранения всего файла потребуется достаточно памяти, это не рекомендуется при работе с большими файлами.источник
Вот более общий подход, работает с uniq, sort и так далее.
источник
sponge
от moreutils:cat file |frobnicate |sponge file
.Комментарий Тобу о губке требует самостоятельного ответа.
Цитата с домашней страницы moreutils :
Однако он
sponge
страдает той же проблемой, которую здесь комментирует Стив Джессоп. Если какая-либо из команд в конвейере до этогоsponge
не удалась, исходный файл будет перезаписан.Ой-ой,
my-important-file
ушел.источник
set -o pipefail
в начале своего скрипта, ошибкаmistyped_command my-important-file
заставит скрипт немедленно завершиться, прежде чем он будет выполненsponge
, таким образом сохраняя важный файл.Вот и все, одна строка:
Технически здесь нет копирования во временный файл, и команда «mv» должна быть мгновенной.
источник
Мне нравится
sort file -o file
ответ, но я не хочу дважды вводить одно и то же имя файла.Использование расширения истории BASH :
захватывает первый аргумент текущей строки при нажатии enter.
Уникальная сортировка на месте:
захватывает последний аргумент в текущей строке.
источник
Многие упоминали параметр -o . Вот часть справочной страницы.
На странице руководства:
источник
Это будет сильно ограничено памятью, но вы можете использовать awk для хранения промежуточных данных в памяти, а затем записать их обратно.
источник
>
файл обрезается до того, как команда (uniq
в данном случае) его прочитает.Альтернатива
sponge
более распространеннымsed
:Она работает для любой команды (
sort
,uniq
,tac
...) и использует очень хорошо известныsed
«s-i
вариант (редактировать файлы на месте).Предупреждение: попробуйте
command file
сначала, потому что редактирование файлов на месте небезопасно по своей природе.объяснение
Во - первых, вы говорите ,
sed
не печатать (оригинальное) линии (-n
опция ), а также с помощьюsed
«sr
команды иbash
» s Подстановка процессов , генерируемый контент путем<(command file)
будет выход сохранен на месте .Делаем вещи еще проще
Вы можете превратить это решение в функцию:
пример
источник
Используйте аргумент
--output=
или-o
Только что попробовал на FreeBSD:
источник
Чтобы добавить
uniq
возможность, каковы недостатки:источник
Прочтите о неинтерактивном редакторе
ex
.источник
Если вы настаиваете на использовании
sort
программы, вам нужно использовать промежуточный файл - я не думаю, чтоsort
есть возможность сортировки в памяти. Любой другой трюк с stdin / stdout потерпит неудачу, если вы не можете гарантировать, что размер буфера для stdin сортировки достаточно велик, чтобы вместить весь файл.Изменить: позор мне.
sort temp.txt -o temp.txt
работает отлично.источник
Другое решение:
источник
<>
трюк работает только в этом случае, потомуuniq
что он особенный в том, что он только копирует входные строки в выходные строки, удаляя некоторые по пути. Если использовалась другая команда (напримерsed
), которая изменила бы ввод (например, изменила бы каждыйa
наaa
), тогда она может переопределитьfile
способами, которые не имеют никакого смысла, и даже бесконечный цикл, при условии, что ввод достаточно велик (больше, чем одиночный буфер чтения).