Unixで再帰関数呼び出しを作成する方法

Unixで再帰関数呼び出しを作成する方法
#!/bin/sh
checking()
{
  cd "$1"
  for D in *;do
    if [ -d "$D" ]; then
      cd "$D"
      for d in *;do
        echo "$d"
        if [ -d "$d" ]
        then
           `checking() $d`
        fi
        if [ -f "$d" ]
        then
                file_name=`echo "$d" | cut -d'.' -f1`
                echo $file_name
                file_ext=$(echo $d |awk -F . '{if (NF>1) {print $NF}}')
                echo $file_ext
                if [ $file_ext = bin ]
                then
                        strings $d > $file_name.txt
                        mv $file_name.txt /somepath
                fi
        fi

      done
      cd ..

    fi
  done
}

a=$(pwd)
checking() $a

セッションログバイナリファイルをテキストファイルに変換し、文字列関数を使用して特定のパスに保存しています。すべてのディレクトリに対してうまく機能しますが、バイナリ内にサブディレクトリがあることを確認しません。

再帰関数呼び出しを試しましたが、呼び出しは実行されません。助けてください

ベストアンサー1

あなたの機能でいくつかのことを発見しました。

  • ディレクトリに移動してファイルを繰り返し、両方を実行します。再びcd; for d in *; do cd; for d in * ...)。これは、再帰巡回中にディレクトリツリーの他のすべてのレベルをスキップするようです。ファイルを一度だけ繰り返すだけで十分です。
  • 関数を再帰的に呼び出すときにサブシェルを使用する必要はないようです(にバックティックコマンドの置き換えがあります`checking() $d`)。これは、関数呼び出しの各インスタンスにローカル変数が必要な場合に便利ですが、多くのシェルでこれを直接実行できます(localBashでは明らかtypesetにksh93で)
  • もちろん、関数を呼び出す構文もあります。hi() { echo "hello $1"; }他のコマンドのように実行すると仮定しますhi "$name"
  • キャンセルawkしてシェルを使用できますパラメータ拡張ファイル拡張子を選択してください。 (ただし、ファイル名に点がない場合は境界線を確認してください。)case "$f" in *.bin) ...

以下は、ディレクトリツリーをナビゲートする非常に単純な関数です。

#!/bin/sh

walk() {
        cd "$1"
        for f in *; do 
                if [ -d "$f" ] ; then
                        echo descending into "$f"...
                        walk "$f"
                else
                        ext=${f##*.}
                        if [ "$ext" = "bin" ] ; then
                                echo "found .bin file: $f"
                        fi
                fi

        done
        cd ..
}

walk .

cd "$dir"; ... ; cd ..(しかし、この構造は、プログラムが処理中に誰かがディレクトリを移動すると問題を引き起こす可能性があることに注意してください。..リンクは変更され、それを介して戻ることは元のツリーの外側にある可能性がある新しい場所に続きます。このようにすることができますpushd/popd(Bashで)使用するか、関数全体を配置するか、サブシェルから呼び出して、絶対パス名を使用してこの問題を解決します。

おすすめ記事