
Eu tenho vários arquivos markdown em minha pasta que gostaria de converter para html com pandoc.
O comando que normalmente uso é
pandoc Atten.md -f markdown -t html --css pandoc.css -o Atten.html
onde Atten.md
está o nome de um arquivo markdown típico. No entanto, gostaria de iterar todos os arquivos e converter .md em .html conforme feito acima. Como faço isso no bash ou zsh?
Responder1
Com find
:
find path/to/dir -name "*.md" -type f -exec sh -c '
pandoc -f markdown -t html --css pandoc.css -o "${1%.*}.html" "$1"
' find-sh {} \;
Deve funcionar em Bash, Zsh e muitos outros shells. A única tarefa do shell externo é executar find
com argumentos adequados.
Esta versão gera um único sh
para processar tantos arquivos quanto possível (mais sh
processos serão gerados se necessário):
find path/to/dir -name "*.md" -type f -exec sh -c '
for f; do
pandoc -f markdown -t html --css pandoc.css -o "${f%.*}.html" "$f"
done
' find-sh {} +
Notas:
- O shell interno é invocado apenas porque precisamos remover a extensão antiga. Se não fosse o requisito, uma solução
… -exec pandoc … -o {}.html {} \;
provavelmente funcionaria. "Provavelmente" porque o POSIX exigefind
a substituição de um único arquivo{}
. É uma "cortesia" dafind
implementação que você usa, se algo mais for substituído (como{}.html
ou a segunda aparição de{}
). -execdir
em vez de-exec
seria melhor, mas não é POSIX.-execdir
nos permitiria usar./"$1"
em vez de"$1"
(respectivamente:./"$f"
em vez de"$f"
) para evitar que fosse interpretado porpandoc
como uma opção. Outra abordagem é--
mas não sei sepandoc
apoia. Acho que no seu caso"$1"
não é possível expandir para nada que comece com-
porque deve começar compath/to/dir
e, sepath/to/dir
iniciado com-
, seria mal interpretadofind
em primeiro lugar. Em geral, embora esta preocupação seja legítima.Na
pandoc
invocação, movi o operando para o final apenas por causa de minha preferência pela ordem mais comum decommand -options operands
.A solução é recursiva. Para torná-lo não recursivo, especifique
-maxdepth 1
. Se vocêfind
não apoia-maxdepth
então estudeesseou soltefind
e deixe o shell externo iterar sobre os arquivos:# written for Bash ( cd path/to/dir || exit 125 for f in ./*.md ./.*.md; do [ -f "$f" ] && pandoc -f markdown -t html --css pandoc.css -o "${f%.*}.html" "$f" done )
Notas específicas para o código acima:
- O subshell deve
cd
funcionar sem afetar o shell atual. - Se
cd
falhar por qualquer motivo, o restante não será executado. Esta é uma boa prática. ./*.md
em vez de simples*.md
impede"$f"
que seja interpretado como uma opção posteriormente../.*.md
é adicionado porque./*.md
não corresponde a dotfiles.[ -f "$f" ]
é prevenir- invocando
pandoc
diretórios, arquivos especiais e outros; - invocando
pandoc
inexistente./*.md
(ou./.*.md
) quando nada corresponde ao padrão.
- invocando
Zsh é um pouco diferente. O código deve funcionar
sh
e, como um subshell é útil de qualquer maneira, não faria muita diferença se você chamassesh
explicitamente de qualquer shell sensato:sh -c 'cd path/to/dir || exit 125 for … done '
- O subshell deve
Responder2
Você deve usar find
e seu -exec
(vejahomem encontrar):
find YourDirectory -name \*.md | \
while IFS= read fn; do \
pandoc ${fn} -f markdown -t html --css pandoc.css -o ${fn%.md}.html ; done
Ou talvez -execdir
.
Responder3
Você pode iterar o arquivo com um for:
for item in *.md; do CONVERT_FILE_COMMAND $item "$(basename '$item' .md).html; done