губка от moreutils - какая разница с редиректом оболочки? полезные примеры?


16
> brew install moreutils                                                          
==> Downloading https://homebrew.bintray.com/bottles/moreutils-0.55.yosemite.bottle.tar.gz    
######################################################################## 100.0%               
==> Pouring moreutils0.55.yosemite.bottle.tar.gz       
🍺  /usr/local/Cellar/moreutils/0.55: 67 files, 740K   

Губка читает стандартный ввод и записывает его в указанный файл. В отличие от перенаправления оболочки, губка впитывает весь свой ввод перед записью выходного файла. Это позволяет создавать конвейеры, которые читают и пишут в один и тот же файл.

Я не понимаю Пожалуйста, дайте мне несколько полезных примеров.

Что значит впитывать ?



Еще один пример expand foo.txt | sponge foo.txt. См. Также: stackoverflow.com/a/33639324/1959808
Иоаннис Филиппидис

tl; dr sponge«впитывает» свои данные перед усечением выходного файла
BallpointBen

Ответы:


33

Предположим, что у вас есть файл с именем input, вы хотите удалить все строки, начинающиеся с #in input. Вы можете получить все строки, не начинающиеся с #:

grep -v '^#' input

Но как вы вносите изменения в input? При использовании стандартного инструментария POSIX вам необходимо использовать временный файл, например:

grep -v '^#' input >/tmp/input.tmp
mv /tmp/input.tmp ./input

С перенаправлением оболочки:

grep -v '^#' input >input

будет усекать, inputпрежде чем читать с него.

С помощью spongeвы можете:

grep -v '^#' input | sponge input

4
На самом деле вы можете одновременно безопасно читать и записывать файл, если только байты преобразуются, используя <>оператор.
Крис Даун

@ChrisDown: Да, я имею в виду, не делая это коррумпированным
cuonglm

Я не уверен, что ты имеешь в виду, говоря о том, чтобы "испортить". В отличие от >и <, <>не повреждает файл, если что-то пошло не так. Вы можете довольно легко написать побайтно, используя его. Например, попробуйте использовать его с tr.
Крис Даун

@ChrisDown: Позвольте мне удалить это предложение, чтобы не запутаться. Я имею в виду, что при использовании <>fileвы открываете файл для чтения и записи, но на самом деле вы ничего не записываете в файл.
Cuonglm

1
Я думаю, что @ChrisDown пытается понять, что <>не усекает файл, а просто заменяет существующие байты новым выводом. Если новый вывод слишком короткий, у вас останется мусор в конце файла. Но если новый вывод достаточно длинный, риска нет.
BallpointBen

8

Сама домашняя страница moreutils описывает типичный вариант использования:

sed "s/root/toor/" /etc/passwd | grep -v joey | sponge /etc/passwd

Здесь / etc / passwd одновременно записывается и читается, а также изменяется. Без добавления stdin перед записью файл / etc / passwd может быть поврежден (так как файл изменился во время чтения).


И это был бы хороший пример на странице moreutils, если бы он объяснил, как вы это сделали :-)
Br.Bill
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.