bashでフォルダ内のすべてのファイルを反復処理する

bashでフォルダ内のすべてのファイルを反復処理する

フォルダー内にマークダウン ファイルがたくさんあり、これを pandoc を使用して HTML に変換したいと考えています。

私がよく使うコマンドは

pandoc Atten.md -f markdown -t html --css pandoc.css -o Atten.html

典型的なマークダウン ファイルの名前はどこにAtten.mdありますか。ただし、すべてのファイルを反復処理し、上記のように .md を .html に変換したいと思います。これを bash または zsh で実行するにはどうすればよいですか?

答え1

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 {} \;

これは、Bash、Zsh、その他多くのシェルで動作するはずです。外側のシェルの唯一の役割は、find適切な引数で実行することです。

shこのバージョンでは、できるだけ多くのファイルを処理するために単一のプロセスが生成されます(sh必要に応じて、さらにプロセスが生成されます)。

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 {} +

ノート:

  • 内部シェルが呼び出されるのは、古い拡張機能を削除する必要があるためです。それが要件でない場合は、 を使用したソリューションが… -exec pandoc … -o {}.html {} \;おそらく機能します。「おそらく」というのは、POSIX ではfind1 つの のみを置き換える必要があるためです。さらに何かを置き換える場合 ( やの 2 回目の出現など) 、これは使用する実装{}の「礼儀」です。find{}.html{}
  • -execdirの代わりに の-exec方が良いですが、これは POSIX ではありません。
  • -execdir(それぞれ の代わりに)を使用する./"$1"ことで、 がオプションとして解釈されるのを防ぐことができます。別のアプローチは"$1"./"$f""$f"pandoc--しかし、 がそれをサポートしているかどうかはわかりませんpandoc。あなたの場合、は で始まる必要があり、 で始まると、そもそも によって誤解されるため、で始まる"$1"ものに拡張することはできないと思います。しかし、一般的には、この懸念は正当です。-path/to/dirpath/to/dir-find
  • 呼び出しでは、pandoc最も一般的な順序に対する私の好みのためだけに、オペランドを最後に移動しましたcommand -options operands

  • 解決策は再帰的です。再帰的でないようにするには を指定します-maxdepth 1。 がfindサポートしていない場合は-maxdepth、 を調べてください。これまたはドロップしてfind、外側のシェルにファイルを反復処理させます。

    # 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 )
    

    上記コードに固有の注意事項:

    • サブシェルは、cd現在のシェルに影響を与えずに動作します。
    • 何らかの理由で失敗した場合はcd、残りは実行されません。これは良い方法です。
    • ./*.mdプレーンの代わりに使用すると、後でオプションとして解釈されるのを*.md防ぎます。"$f"
    • ./.*.md./*.mdドットファイルと一致しないため追加されます。
    • [ -f "$f" ]防止することです
      • pandocディレクトリ、特殊ファイルなどを呼び出す。
      • パターンに一致するものがない場合は、存在しない(または)pandocを呼び出します。./*.md./.*.md
    • Zsh は多少異なります。ただし、コードは動作するはずです。サブシェルはとにかく便利なので、正常なシェルから明示的にsh呼び出しても大きな違いはありません。sh

      sh -c 'cd path/to/dir || exit 125
             for …
             done '
      

答え2

find-exec(参照)を使用する必要があります男が見つけた):

find YourDirectory -name \*.md | \
  while IFS= read fn; do \
  pandoc ${fn} -f markdown -t html --css pandoc.css -o ${fn%.md}.html ; done

または多分-execdir

答え3

for を使用してファイルを反復処理できます。

for item in *.md; do CONVERT_FILE_COMMAND $item "$(basename '$item' .md).html; done

関連情報