だから私はファイルサイズが与えられた引数より小さいことを確認し、trueの場合はecho "YES"と言う簡単なスクリプトを書いています。
#!bin/bash
Function ()
{
cd $1
lista=`ls`
for item in $lista
do
if [ ! -d $item ]
then
size=`wc -c $item | awk '{ print $1 }'`
if [ $size -lt $2 ]
then
echo "$item"
fi
else
Function $item $2
fi
cd ..
done
}
Function $1 $2
そしてカーニバル:
bash test2.sh /home/161161 300
しかし、2番目のループを実行した後、そのファイルが存在しないか存在しないというエラーが発生するため、wc -cに問題があります。
どんなアイデアがありますか?
答え1
問題は、cd ..
ディレクトリ内のすべてのファイルが完了する前にコードが完了することです。一般的に言えば、ファイル名を取得するためにディレクトリに移動する必要はなく、cd
ループからディレクトリに前後に移動するのは混乱する可能性があります。ループ内の出力を相対パスなどを使用してファイル名にリダイレクトすると、奇妙な問題が発生する可能性があります。このスクリプトでは不明どこ(あるディレクトリでは)常に現在のディレクトリを表示するため、ファイルが見つかります。
を無効にするcd
か無効にすることでこの問題を解決してくださいls
。これにより、スクリプトでスペースやその他の珍しい文字を含むファイル名を使用できます。
#!/bin/sh
find_smaller () {
dir=$1
size=$2
for pathname in "$dir"/*; do
if [ -f "$pathname" ]; then
# this is a regular file (or a symbolic link to one), test its size
filesize=$( wc -c <"$pathname" )
if [ "$filesize" -lt "$size" ]; then
printf 'Found %s, size is %d\n' "$pathname" "$filesize"
fi
elif [ -d "$pathname" ]; then
# this is a directory (or a symbolic link to one), recurse
printf 'Entering %s\n' "$pathname"
find_smaller "$pathname" "$size"
fi
done
}
find_smaller "$@"
上記のコードでは、現在表示され$pathname
ているファイルまたはディレクトリのファイル名だけでなく、起動ディレクトリへの相対パスも表示されます。
また、すべての変数拡張への参照も参照してください。$pathname
たとえば、ファイル名に*
または同じ文字が含まれている場合は、変数を引用せずにファイル名globbingを呼び出します?
。
また見なさい:
- スペースやその他の特殊文字が原因でシェルスクリプトが停止するのはなぜですか?
- なぜ`ls`を解析しないのですか?
- なぜprintfがechoより優れているのですか?
- * shシェルではバックティック(「cmd」など)は使用されなくなりましたか?
bash
シェルオプションを使用してくださいglobstar
。このオプションを設定すると、**
グローバルパターンは指定されたディレクトリの下のすべてのパス名と一致します。これは、スクリプトがディレクトリ構造を明示的に移動する必要がないことを意味します。
#!/bin/bash
dir="$1"
size="$2"
shopt -s globstar
for pathname in "$dir"/**; do
[ ! -f "$pathname" ] && continue
filesize=$( wc -c <"$pathname" )
if [ "$filesize" -lt "$size" ]; then
printf 'Found %s, size is %d\n' "$pathname" "$filesize"
fi
done
find
次のfind
コマンドを使用して、コードで実行したい操作を実行できます。
find /home/161161 -type f -size -100c
スクリプトとして:
#!/bin/sh
dir=$1
size=$2
find "$dir" -type f -size -"$size"c
明示的なディレクトリウォーカーとバリアントfind
の間の唯一のわずかな違いfind
は、(上記のように使用されている場合)シンボリックリンクが無視されるのに対して、上記のシェル関数はシンボリックリンクを解決してディレクトリループが無限に検索されるか、同じデータが計算されることです。あまりにも移流。
を使用すると、find
ファイルのサイズを計算するためにファイルの内容を読み取ることはできません。代わりに、lstat()
ファイルシステムでファイルサイズを照会するためにライブラリが呼び出されます。これはたくさんを使用するよりも数倍速いですwc -c
!
すべてではありませんが、ほとんどのUnicesではコマンドラインユーティリティを使用してstat
ファイルサイズを確認できます。使用方法については、システムのユーティリティのマニュアルを参照してください(LinuxとBSDでは動作が異なります)。