Запустите команду для одного файла, когда измените его с помощью некоторой магии оболочки (например, замените расширение)
Я пишу несколько файлов .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)