Подтвердить что ты не робот

Почему не выполняется сортировка файла file1> file1?

Когда я пытаюсь сортировать файл и сохранять отсортированный вывод сам по себе, например

sort file1 > file1;

содержимое файла1 полностью стирается, тогда как когда я пытаюсь сделать то же самое с командой "tee", как этот

sort file1 | tee file1;

он отлично работает [ed: "отлично работает" только для небольших файлов с удачным сроком, приведет к потерям данных на больших или с бесполезным планированием процессов], то есть перезаписывает отсортированный вывод file1, а также показывая его на стандартном выходе.

Может кто-нибудь объяснить, почему первый случай не работает?

4b9b3361

Ответ 1

Это не работает, потому что перенаправление " > " подразумевает усечение, и чтобы избежать сохранения всего вывода sort в памяти перед повторным направлением к файлу, bash обрезает и перенаправляет вывод перед запуском sort, Таким образом, содержимое файла file1 будет усечено до того, как sort будет иметь возможность прочитать его.

Ответ 2

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

Команда sort имеет "всегда" (поскольку, по крайней мере, версия 7 UNIX) поддерживает параметр -o, чтобы сделать его безопасным для вывода на один из входных файлов:

sort -o file1 file1 file2 file3

Трюк с tee зависит от времени и удачи (и, возможно, небольшого файла данных). Если у вас был мегабайт или более крупный файл, я ожидаю, что он будет скроен, по крайней мере частично, командой tee. То есть, если файл достаточно велик, команда tee откроет файл для вывода и усекает его до того, как sort закончит чтение.

Ответ 3

Неразумно зависеть от любой из этих команд, чтобы работать так, как вы ожидаете.

Способ изменения файла на месте - это записать измененную версию в новый файл, а затем переименовать новый файл в исходное имя:

sort file1 > file1.tmp && mv file1.tmp file1

Это позволяет избежать проблемы с чтением файла после его частичного изменения, что, вероятно, испортит результаты. Это также позволяет грамотно справляться с ошибками; если файл имеет длину N байтов и в файловой системе имеется только N/2 байта пространства, вы можете обнаружить сбой создания временного файла и не выполнять переименование.

Или вы можете переименовать исходный файл, затем прочитать его и записать в новый файл с тем же именем:

mv file1 file1.bak && sort file1.bak > file1

Некоторые команды имеют опции для изменения файлов на месте (например, perl и sed оба имеют параметры -i (обратите внимание, что синтаксис опции sed -i может меняться). Но эти параметры работают путем создания временные файлы, это просто сделано внутренне.

Ответ 4

Bash открыть новый пустой файл при чтении канала, а затем вызывает сортировку.

Во втором случае tee открывает файл после сортировки, уже прочитавшего содержимое.

Ответ 5

Перенаправление имеет более высокий приоритет. Итак, в первом случае > file1 выполняет первый и опустошает файл.

Ответ 6

Первая команда не работает (sort file1 > file1), потому что при использовании оператора перенаправления (> или >>) оболочка создает/обрезает файл до того, как команда sort даже вызывается, так как она имеет более высокий старшинство.

Вторая команда работает (sort file1 | tee file1), потому что sort сначала считывает строки из файла, затем записывает отсортированные данные в стандартный вывод.

Поэтому при использовании любой другой подобной команды вам следует избегать использования оператора перенаправления при чтении и записи в один и тот же файл, но для этого вам следует использовать соответствующие редакторы на месте (например, ex, ed, sed), например:

ex '+%!sort' -cwq file1

или использовать другие утилиты, такие как sponge.

К счастью для sort существует параметр -o, который записывает результаты в файл (как это предложено @Jonathan), поэтому решение прямолинейно: sort -o file1 file1.

Ответ 7

Вы можете использовать этот метод

sort file1 -o file1

Это приведет к сортировке и сохранению исходного файла. Кроме того, вы можете использовать эту команду для удаления дублированной строки:

sort -u file1 -o file1