1

Я пишу несколько файлов .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

Следующие работы

  1. Простая печать последнего измененного файла

    $ ls *.gv | entr echo /_
    # Press <Space> to manually trigger event to see last changed file
    /Users/hotschke/complete.gv
    
  2. Используя одно и то же имя вывода для всех файлов:

    $ ls *.gv | entr neato -Tpng /_ -oConstantname.png
    
  3. Заменить .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 ответа4

2

Вызовите скрипт с 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).

1

Использование 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)

1

Использование 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:

Это означает, что вам не нужно писать Makefile. Вы можете установить makeprg с помощью :comp[iler] neato или :comp dot . Обратите внимание, что вы видите все определения компилятора по :comp <C-d> и можете завершить табуляцию :comp n<Tab> в :comp neato и :comp d<tab> to :comp dot .

Теперь вам нужно вызвать make с аргументом, чтобы указать формат вывода:

:make png
:au BufWritePost <buffer> make png

Если вы используете vim-dispatch, это выглядит так

:Make png
m<Space>png<CR>
:au BufWritePost <buffer> Make png
0

Entr - Pass /_ в качестве аргумента для оболочки

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#comment-44183153.

Эта команда молча выполняет команду neato . Если вы хотите получить обратную связь в командной строке, когда entr обнаружит изменение файла, добавьте -x в bash, чтобы увидеть выполненную команду:

ls *.gv | entr bash -x -c 'neato -Tpng "$0" -o"${0/%\.gv/.png}"' /_

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .