#!/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 * ...
)。これは、再帰的にディレクトリツリーを巡回する間に、ディレクトリツリーの他のすべてのレベルをスキップするようです。ファイルに対する1回の反復で十分でしょう。 - 関数を再帰的に呼び出すときにサブシェルを使う必要はないと思います( にはバックティックコマンド置換があります
`checking() $d`
)。関数呼び出しの各インスタンスにローカルな変数が必要な場合には便利ですが、多くのシェルではそれを直接行うことができます(local
Bashでは を使用します)。どうやら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 の場合) を使用するか、関数全体またはその呼び出しをサブシェルに配置することで、この問題を回避できます。)