#!/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 * ...
)。這似乎會在遞歸遍歷期間跳過目錄樹的所有其他層級。對文件進行一次迭代就足夠了 - 我認為在遞歸呼叫該函數時不需要使用子shell(在 中存在反引號命令替換
`checking() $d`
)。如果您需要函數呼叫的每個實例的本地變量,這可能很有用,但許多 shell 可以直接執行此操作(local
在 Bash 中使用,顯然是typeset
在 ksh93 中) - 當然還有呼叫函數的語法:假設
hi() { echo "hello $1"; }
我們像任何其他命令一樣運行它,只需使用hi "$name"
. - 我們可以取消
awk
並使用 shell 的參數擴充選擇檔案副檔名。 (但當檔案名稱中沒有點時,請檢查邊界大小寫。)或使用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 中),或將整個函數或對它的呼叫放在子 shell 中。