wc -c はスクリプトのループでは機能しません。

wc -c はスクリプトのループでは機能しません。

だから私はファイルサイズが与えられた引数より小さいことを確認し、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を呼び出します?

また見なさい:


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では動作が異なります)。

おすすめ記事