Неге «file1> file1 сұрыптау» жұмыс істемейді?

Мен файлды сұрыптап, сұрыпталған нәтижені өзі сияқты сақтауға тырысқанда

sort file1 > file1;

file1 мазмұны толығымен жойылады, ал мен сияқты «tee» пәрменімен бірдей жасауға тырысқанда

sort file1 | tee file1;

[ed: «сәтті уақытты кішкене файлдар үшін ғана жұмыс істейді, үлкендерде жоғалған деректерді немесе пайдалы процесті жоспарлаусыз жоғалтуы мүмкін] жұмыс істейді, яғни ол файл1 ішіндегі сұрыпталған нәтижені қайта жазады сондай-ақ оны стандартты шығаруда көрсету.

Біреу түсіндіре алады, неге бірінші жағдайда жұмыс істемейді?

16
қосылды автор outis, көзі

7 жауаптар

Басқа адамдар түсіндіргендей, мәселе сұрыптау командасы орындалу алдында енгізу/шығару жөнелту мәселесі болып табылады, сондықтан sort бұған оқу мүмкіндігін алдыға дейін қысқартады . Егер сіз біраз ойласаңыз, неге анық көрінеді - қапшық I/O қайта бағыттауды басқарады және бұйрықты орындамас бұрын мұны істеу керек.

sort пәрмені 'әрқашан' бар (кемінде 7 нұсқасы UNIX) -o параметрін қолжетімді енгізу файлдарының біреуіне қауіпсіз ету үшін:

sort -o file1 file1 file2 file3

tee әдісі уақыт пен сәттілікке байланысты (және, шамасы, шағын деректер файлы). Егер сізде мегабайт немесе үлкенірек файл болса, ол tee командасымен кем дегенде ішінара жабылады деп күтемін. Яғни, егер файл жеткілікті үлкен болса, tee командасы файлды шығару үшін ашып, оны sort оқуды аяқтағанға дейін қысқартады.

17
қосылды
+1. Ол әрқашан адам бетін оқуға төлейді
қосылды автор Alexander Pogrebnyak, көзі

It doesn't work because '>' redirection implies truncation, and to avoid keeping the whole output of sort in the memory before re-directing to the file, bash truncates and redirects output before running sort. Thus, contents of the file1 file will be truncated before sort will have a chance to read it.

14
қосылды
Бұл файлға қайта бағыттамас бұрын, жадта сұрыптаудың барлық түрін сақтаудан аулақ болуға болмайды және «bash» -ге тән емес. > анықталған басымдылығы бағдарламаны орындаудан бұрын бағаланады, бұл қарапайым, барлық қабықшаларда.
қосылды автор EJP, көзі

Осы команданың кез келгеніне күткендей жұмыс істеудің ақылға қонбауы мүмкін.

Файлды өзгерту тәсілі - өзгертілген нұсқаны жаңа файлға жазу, содан кейін жаңа файлды түпнұсқа атына қайта атау:

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

Бұл файлды ішінара өзгертілгеннен кейін оқу туралы мәселені болдырмайды. Сондай-ақ, ол қателіктермен керемет түрде айналысуға мүмкіндік береді; егер файл N байт ұзын болса және файл жүйесінде қол жетімді бос орынның тек N/2 байті болса, сіз уақытша файлды жасаған сәтсіздікті анықтай аласыз және атын өзгертпейсіз.

Немесе түпнұсқалық файлдың атауын өзгертіп, оны оқып, сол атпен жаңа файлға жаза аласыз:

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

Кейбір пәрмендерде файлдарды орнына өзгерту мүмкіндіктері бар (мысалы, perl және sed ) -i параметрлері бар (назар аударыңыз, code> -i параметрі өзгеруі мүмкін), бірақ бұл опциялар уақытша файлдар жасау арқылы жұмыс істейді, ол тек ішкі түрде жасалады.

4
қосылды
Жақсы - бірақ sort -o file1 file1 әлдеқайда қарапайым және қауіпсіз.
қосылды автор Jonathan Leffler, көзі

Бұл әдісті қолдануға болады

sort file1 -o file1

Бұл бастапқы файлды сұрыптайды және сақтайды. Сондай-ақ, осы пәрменді қайталанатын сызықты жою үшін пайдалануға болады:

sort -u file1 -o file1
2
қосылды
Және нақты сұраққа жауап бермейді.
қосылды автор EJP, көзі
Қазірдің өзінде бірнеше жыл бұрын айтылған.
қосылды автор Nathan Tuggy, көзі

The first command doesn't work (sort file1 > file1), because when using the redirection operator (> or >>) shell creates/truncates file before the sort command is even invoked, since it has higher precedence.

sort алдымен файлдан жолдарды оқиды, содан кейін сұрыпталған деректерді стандартты шығысқа жазады, себебі екінші команда жұмыс істейді ( sort1 файлын ).

Сондықтан кез-келген басқа ұқсас пәрменді қолданғанда, сол файлды оқу және жазу кезінде қайта бағыттау операторын пайдаланудан аулақ болуыңыз керек, бірақ сол үшін тиісті редакторларды қолданыңыз (мысалы, ex , ed , sed ), мысалы:

ex '+%!sort' -cwq file1

немесе sponge секілді басқа утилиттерді қолданыңыз.

Бақытымызға орай, sort үшін нәтижеге файлға жазатын -o параметрі бар ( @ Jonathan ), сондықтан шешім тікелей алға: sort -o file1 file1 .

1
қосылды

Redirection has higher precedence. So in the first case, > file1 executes first and empties the file.

1
қосылды

Башта құбырды оқи отырып, жаңа бос файлды ашып, сұрыптауға шақырады.

Екінші жағдайда, сұрыптау мазмұнды оқығаннан кейін tee файлды ашады.

1
қосылды
'tee' өзінің файлын ашқанда 'sort' ашылған кезде, белгілі бір уақыт ішінде файлды ашады. Кейде сіз бақытты боласыз, кейде сізде жоқ. «Сұрыптау» барлық мазмұнды оқып шығуы қажет емес, тек алдымен файлды ашқан.
қосылды автор EJP, көзі