Як працюють>> і> >>?


9

Я спробував revфайл, а потім передати cat > same_fileйого, але він перетворювався на порожній файл.

Поки я намагався rev file.txt | cat > file2.txt && mv file.txt file2.txt;це спрацювало.

Навіть rev file.txt | cat >> file.txt;працював.

Але коли я спробував rev file.txt | cat > file.txtце не вдалося.


Ви також можете залишити catось так: rev file.txt > file2.txt && mv file2.txt file.txt. Це зайве використанняcat . Залишивши його, ви запасите нерест додатковим процесом.
матега

Відповіді:


19

Основне, що вам потрібно зрозуміти в цьому випадку між обома способами переадресації (> та >>), це:

>

Перенаправляє та переписує інформацію, на яку вона вказувала. Це відбувається під час отримання будь-якої інформації через трубу "|"

>>

Перенаправляє та зв'язує інформацію, на яку вказували. Це відбувається під час отримання будь-якої інформації через трубу "|"

В обох випадках, якщо файл не існує, він буде створений замість цього. Тільки на ">>" інформація буде об'єднана, якщо ви знову запустите її в тому ж файлі. За допомогою ">" ви просто перезаписаєте все, що зробили під час першого запуску.

Але ось угода, коли використовується той же вхідний файл, що і вихідний файл. У цьому конкретному випадку, якщо ви використовуєте ">", ви видаляли б інформацію, яку "вхідна" частина повинна проаналізувати, оскільки вихідний файл буде "перезаписати її". Так у:

rev file.txt | cat > file.txt

Що насправді відбувається в "поясненні повільного руху", це:

  1. revготується до реверсування вмісту file.txtта відправлення його на розсип
  2. Поки revпередає інформацію в трубу, труба передає її безпосередньо cat.
  3. Поки catотримує інформацію, вона автоматично застосує її до тієї, для якої file.txtвона була встановлена.
  4. Ключове слово тут "поки", тому що все відбувається одночасно. Будь ласка, дивіться чудові коментарі Еміля нижче, щоб глибше зрозуміти цю частину.
  5. catне чекатиме revпередачі всього файлу. Він просто розпочне хвилину, коли перша частина інформації потрапить до неї, а це означає, що залежно від того, який символ ви використовували, він відкриє з'єднання file.txt.
  6. У цьому випадку, оскільки ви використовували >, а не >> , оболонка буде усікати вихідний файл, що означає, що він відкриє та очистить інформацію, file.txtпоки очікує на отримання нової інформації до неї. З >> він би відкрив з'єднання з file.txtі чекав нової інформації на останньому виявленому рядку.
  7. Так як інформація вже була очищена в file.txtс > , revбуде намагатися зробити свою роботу і нічого не отримати , тому що catвидалені всі в рамках підготовки до нової інформації.

То чому ж інші працюють, прочитавши вище. Через це:

rev file.txt | cat > file2.txt && mv file.txt file2.txt

Тут ви перекладаєте на кота, який надсилає інформацію в інший файл. У цьому випадку оброблений вхідний файл file.txtне збігається з вихідним файлом file2.txt. Після того, що ви буквально перезаписувати все file2.txtз file.txt, так що весь процес зроблений catбув видалений. В основному, весь рядок може бути спрощений, як і cp file.txt file2.txtтому, що він робить те саме, оскільки file2.txtв кінці втрачає revта перезаписується mvкомандою.

rev file.txt | cat >> file.txt

У цьому випадку ви об'єднуєте інформацію в один і той же файл. Таким чином, це лише відкриття з'єднання з цим файлом, але не стирання інформації, як видно з одного > . Кінцевим результатом має бути оригінальна інформація плюс зворотна інформація.


5
Файл не усічений кіткою. Вона обрізана оболонкою, перш ніж будь-яка команда в трубопроводі навіть запуститься.
Еміль Єржабек

Правильно, шукав легших слів для пояснення. Оскільки це трохи важко пояснити, якщо ОП не знає, що це оболонка, і все таке. Намагаючись зробити це максимально "доброзичливим".
Луїс Альварадо

1
Ну, насправді не важливо, що це робиться оболонкою, але що термін, який ви представляєте, неправильний. Відсікання не відбудеться на кроці 6, але на кроці 0. rev file.txt | cat --bogus-option > file.txtтакож буде усічений файл, навіть незважаючи на те, що кішка не намагатиметься його відкрити.
Еміль Єржабек

@ EmilJeřábek ви праві. І все ж користувачам, які не знають, як це поводиться, буде легше, якщо ми підемо крок за кроком лише з командами. Крім того, ваш приклад все ще надсилає інформацію в той самий файл, тому bash прочитає цілий рядок, побачить вихід і все ще відкриє І скоротить його. Помилка - це просто більш жорсткий вихід на stdout.
Луїс Альварадо

4
Дивіться також moreutils , фантастичну колекцію інструментів (доступних із сховища пакетів як moreutils), що включає spongeв себе інструмент, спеціально розроблений для використання шаблону перезапису вхідного файлу. Наприклад, було rev file.txt >file2.txt && mv file2.txt file.txtб вирішене рішення rev file.txt | sponge file.txt, яке буде працювати правильно навіть тоді, коли вже є щось назване file2.txt.
Даніель Вагнер

9

Коли оболонка бачить перенаправлення, вона спочатку відкриває відповідні файли, перш ніж виконати будь-яку із задіяних команд. Таким чином, коли ви робите:

foo file.txt | bar > file.txt

Перенаправлення file.txtзмушує його скорочуватись до foo запуску і може читати file.txt. Зі сторони, ось чому ви не можете:

sed 'blah' file.txt > file.txt

І чому sedє можливість редагування на місці.

Нарешті, роблячи:

.. | cat > file.txt

це марне використання кота , тим більше, якщо ви намагаєтеся читати з file.txtраніше.

Якщо ви хочете змінити файл на місці, ярликів немає . Можливо, вам вдасться скористатись трюками sedабо awkприйомами з місцевим редагуванням.


3

>це переспрямовувач (оператор), що надсилає вихід на щось інше
(введення наступної команди, принтера ..)

У вашому випадку результат виходить у файл file.txt, якщо цей файл вже існує, він буде перезаписаний, якщо ні - він створений.

>>є оператором додавання, якщо file.txtвже існує вихід, додається в кінці файлу. якщо файл не існує, він створюється, і вихід записується в новий файл, такий же, як >(переспрямовувач).


ОП, здається, це зрозуміло. Здається, плутанина випливає лише з того самого файлу, що знаходиться з обох сторін операторів >та >>.
bzlm

0

Ви можете використовувати Vim в режимі Ex:

ex -sc '%!rev' -cx file.txt
  1. % виберіть усі рядки

  2. ! запустити команду

  3. x зберегти і закрити

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.