
Tengo un montón de archivos de rebajas en mi carpeta que me gustaría convertir a html con pandoc.
El comando que suelo utilizar es
pandoc Atten.md -f markdown -t html --css pandoc.css -o Atten.html
¿Dónde Atten.md
está el nombre de un archivo de rebajas típico? Sin embargo, me gustaría iterar sobre todos los archivos y convertir .md a .html como se hizo anteriormente. ¿Cómo hago eso en bash o zsh?
Respuesta1
Con 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 {} \;
Debería funcionar en Bash, Zsh y muchos otros shells. El único trabajo del caparazón exterior es ejecutar find
con los argumentos adecuados.
Esta versión genera uno único sh
para procesar tantos archivos como sea posible ( sh
se generarán más procesos si es necesario):
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:
- El shell interno se invoca sólo porque necesitamos eliminar la extensión anterior. Si no fuera el requisito, entonces una solución
… -exec pandoc … -o {}.html {} \;
probablemente funcionaría. "Probablemente" porque POSIX requierefind
reemplazar uno único{}
. Es una "cortesía" de lafind
implementación que utiliza, si se reemplaza algo más (como{}.html
la segunda aparición de{}
). -execdir
en lugar de-exec
sería mejor pero no es POSIX.-execdir
nos permitiría usarlo./"$1"
en lugar de"$1"
(respectivamente:./"$f"
en lugar de"$f"
) para evitar que sea interpretadopandoc
como una opción. Otro enfoque es--
pero no sé sipandoc
lo soporta. Creo que en su caso"$1"
no se puede expandir a nada que comience con-
porque debe comenzar conpath/to/dir
, y sipath/to/dir
comienza con entonces , en primer lugar,-
se malinterpretaría con .find
Aunque en general esta preocupación es legítima.En
pandoc
la invocación moví el operando al final solo por mi afición hacia el orden más común decommand -options operands
.La solución es recursiva. Para que sea no recursivo, especifique
-maxdepth 1
. Sifind
no lo apoyas,-maxdepth
entonces estudia.esteo soltarfind
y dejar que el shell externo repita los archivos:# 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 del código anterior:
- El subshell está diseñado para
cd
funcionar sin afectar el shell actual. - Si
cd
falla por cualquier motivo, el resto no se ejecutará. Ésta es una buena práctica. ./*.md
en lugar de simple*.md
impide"$f"
que se interprete como una opción más adelante../.*.md
se agrega porque./*.md
no coincide con los archivos de puntos.[ -f "$f" ]
es para prevenir- invocar
pandoc
directorios, archivos especiales y demás; - invocando
pandoc
inexistente./*.md
(o./.*.md
) cuando nada coincide con el patrón.
- invocar
Zsh es algo diferente. Sin embargo , el código debería funcionar
sh
y, debido a que un subshell es útil de todos modos, no haría mucha diferencia si llamarash
explícitamente desde cualquier Shell sensato:sh -c 'cd path/to/dir || exit 125 for … done '
- El subshell está diseñado para
Respuesta2
Debes usar find
y su -exec
(verhombre encontrar):
find YourDirectory -name \*.md | \
while IFS= read fn; do \
pandoc ${fn} -f markdown -t html --css pandoc.css -o ${fn%.md}.html ; done
O tal vez -execdir
.
Respuesta3
Puede iterar el archivo con un for:
for item in *.md; do CONVERT_FILE_COMMAND $item "$(basename '$item' .md).html; done