Запустите команду для одного файла, когда измените его с помощью некоторой магии оболочки (например, замените расширение)
Я пишу несколько файлов .gv ( graphviz) в одном каталоге и хочу создать файл PNG с neato
немедленно, когда я спас одного из них. Я на MacOS 10.12.6, с zsh
как моя оболочка по умолчанию, и я установил entr
с http://entrproject.org/ для отслеживания изменений файлов. Я попробовал следующую команду без удачи
$ echo $0
-zsh
$ ls *.gv | entr 'F="/_";neato -Tpng "$F" -o"${F/%\.gv/.png}"'
entr: exec F="/_";neato -Tpng "$F" -o"${F/%\.gv/.png}": No such file or directory
Следующие работы
Простая печать последнего измененного файла
$ ls *.gv | entr echo /_ # Press <Space> to manually trigger event to see last changed file /Users/hotschke/complete.gv
Используя одно и то же имя вывода для всех файлов:
$ ls *.gv | entr neato -Tpng /_ -oConstantname.png
Заменить.gv на.png
$ F="/Users/hotschke/complete.gv";neato -Tpng "$F" -o"${F/%\.gv/.png}"
Обратите внимание на специальный аргумент /_
из entr
Специальный
/_
аргумент (несколько аналогично$_
в Perl) предоставляет быстрый способ ссылки на первый файл, который изменился. Если указан один файл, это удобный способ избежать повторного ввода пути:
Было бы здорово получить несколько ответов с использованием различных инструментов (например, watchman, watchdog, fswatch, entr, launchd (только для Mac); см. Также обсуждение https://stackoverflow.com/q/1515730/)
4 ответа
Entr
- Проходить /_
в качестве аргумента к раковине
ls *.gv | entr bash -c 'neato -Tpng "$0" -o"${0/%\.gv/.png}"' /_
Этот ответ от https://bitbucket.org/eradman/entr/issues/75/run-command-on-single-file-when-changed.
Эта команда молча выполняет команду neato
, Если вы хотите иметь обратную связь в командной строке, когда entr
обнаруживает изменение файла, добавляет -x
bash, чтобы увидеть выполненную команду:
ls *.gv | entr bash -x -c 'neato -Tpng "$0" -o"${0/%\.gv/.png}"' /_
Вызовите скрипт с entr
TL; Dr: Pass /_
в качестве аргумента для сценария Do The Thing ™
Вместо того, чтобы пытаться использовать специальные аргументы и переменные, передайте /_
в простой сценарий (который сам может быть однострочным) для генерации png:
$ ls *.gv | entr ./update.sh /_
с update.sh
вдоль линий:
neato -Tpng "$1" -o"${1/%\.gv/.png}"
Я проверил вышеуказанный подход с помощью простого скрипта, чтобы использовать imagemagick для convert
изображение, которое работало без кавычек, но лучше оставить их в случае пробелов и т. д. в именах файлов.
Как примечание, я склонен использовать скрипт обновления с entr
во всяком случае, поскольку это держит вещи яснее для меня. Например, я использую entr
для просмотра исходных файлов LaTeX и создания обновленного PDF, в этом случае запускается скрипт обновления xelatex
, biber
а также обновляет средство просмотра PDF (pkill -HUP mupdf
).
Использование Makefile
SOURCES:=$(shell find . -maxdepth 1 -name '*.gv')
ifndef OTYPE
OTYPE:=png
endif
# use `make OTYPE=pdf` to generate pdfs
TARGETS:=$(SOURCES:.gv=.$(OTYPE))
.PHONY: all clean
all: $(TARGETS)
clean:
rm $(TARGETS)
%.$(OTYPE) : %.gv
neato -T$(OTYPE) $< -o$(basename $<).$(OTYPE)
Теперь вы можете использовать
$ ls *.gv | entr make
Есть место для улучшения: есть две команды для вывода списка файлов с расширением.gv, что противоречит единственному источнику правды (SSOT).
Vim Notes
Вы также можете использовать Makefile внутри текстового редактора vim
:mak[e]
Вы можете автоматически вызвать make при сохранении, установив автокоманду с
:au BufWritePost <buffer> make
Вы можете использовать плагин для запуска make async: посмотрите плагины vim-dispatch (отображение в нормальном режиме m<CR>
), neomake или asyncrun.vim.
Однако уже есть определения компилятора для команд dot и neato:
- https://github.com/vim/vim/blob/master/runtime/compiler/dot.vim
- https://github.com/vim/vim/blob/master/runtime/compiler/neato.vim
Это означает, что вам не нужно писать Makefile. Вы можете установить makeprg с помощью :comp[iler] neato
или же :comp dot
, Обратите внимание, что вы видите все определения компилятора :comp <C-d>
и вы можете завершить вкладку :comp n<Tab>
в :comp neato
а также :comp d<tab>
в :comp dot
,
Теперь вам нужно вызвать make с аргументом, чтобы указать формат вывода:
:make png
:au BufWritePost <buffer> make png
Если вы используете vim-dispatch, это выглядит так
:Make png
m<Space>png<CR>
:au BufWritePost <buffer> Make png
С помощью fswatch
вместо entr
Спасибо @Attie за указание fswatch
из. Следующие работы для меня:
$ fswatch -e ".*" -i "$PWD/[^.]*\\.gv$" -0 $PWD |
xargs -0 -n 1 -I {} sh -c 'F={}; neato -Tpng "$F" -o"${F/%\.gv/.png}"'
По умолчанию fswatch рассматривает все файлы: вам нужно использовать фильтры для ограничения определенного типа файлов (см. https://stackoverflow.com/q/34713278/).
https://emcrisostomo.github.io/fswatch/ Энрико М. Кризостомо (2013-2017)