it-swarm-ja.com

シェルマジックで変更されたときに単一のファイルでコマンドを実行する(拡張子を置き換えるなど)

同じディレクトリにいくつかの 。gv ファイル( graphviz )を書き込んでおり、そのうちの1つを保存したらすぐにneatoを使用してpngファイルを作成したいと考えています。 。私はmacOS10.12.6を使用しており、デフォルトのシェルとしてzshを使用しています。ファイルの変更を監視するために、 http://entrproject.org/ からentrをインストールしました。 。運が悪かったので次のコマンドを試しました

$ 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の$_にいくぶん類似しています)は、変更された最初のファイルを参照する簡単な方法を提供します。単一のファイルがリストされている場合、これはパス名を2回入力しないようにするための便利な方法です。

さまざまなツール(ウォッチマン、ウォッチドッグ、fswatch、entr、launchd(macのみ)など)を使用していくつかの回答があると便利です。ディスカッションも参照してください https://stackoverflow.com/q/1515730/ =)

1
Hotschke

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#comment-4418315 からのものです。

このコマンドは、コマンドneatoをサイレントに実行します。 entrがファイルの変更を検出したときにコマンドラインでフィードバックを受け取りたい場合は、-xをbashに追加して、実行されたコマンドを確認します。

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

entrでスクリプトを呼び出す

tl; dr:スクリプトへの引数として/_をDoTheThing™に渡します

特別な引数や変数をいじくりまわすのではなく、/_を単純なスクリプト(それ自体が1つのライナーにすることができます)に渡して、pngを生成します。

$  ls *.gv | entr ./update.sh /_

次の行に沿ってupdate.shを使用します。

neato -Tpng "$1" -o"${1/%\.gv/.png}"

上記のアプローチを、imagemagickを使用して画像をconvertする簡単なスクリプトでテストしました。これは引用符なしで機能しますが、ファイル名にスペースなどがある場合はそのままにしておくことをお勧めします。

ちなみに、私はentrを使用した更新スクリプトを使用する傾向があります。これにより、状況がより明確になります。たとえば、私はentrを使用してLaTeXソースファイルを監視し、更新されたPDFを生成します。その場合、更新スクリプトはxelatexbiberを実行し、PDFビューア(pkill -HUP mupdf)。

2
bertieb

fswatchの代わりにentrを使用する

fswatchを指摘してくれた@Attieに感謝します。私のために以下の作品:

 $ 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/ Enrico M. Crisostomo(2013-2017)

1
Hotschke

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

改善の余地があります。信頼できる唯一の情報源(SSOT)と矛盾する拡張子.gvのファイルを一覧表示する2つのコマンドがあります。

Vim Notes

テキストエディタvim内でMakefileを使用することもできます

: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>から:comp dotにタブで入力できることに注意してください。

次に、出力形式を指定するために、引数を指定してmakeを呼び出す必要があります。

:make png
:au BufWritePost <buffer> make png

Vim-dispatchを使用する場合、これは次のようになります。

:Make png
m<Space>png<CR>
:au BufWritePost <buffer> Make png
1
Hotschke