8

「Test」という文字列で始まるファイル名が $Temp に存在するかどうかを通知する簡単なスクリプトを作成しようとしています。

たとえば、これらのファイルがあります

Test1989.txt
Test1990.txt
Test1991.txt

次に、ファイルが見つかったことをエコーし​​たいだけです。

たとえば、次のようなものです。

file="home/edward/bank1/fiche/Test*"
if  test -s "$file" 
then 
    echo "found one"
else 
    echo "found none"
fi

しかし、これはうまくいきません。

4

7 に答える 7

8

1つのアプローチ:

(
  shopt -s nullglob
  files=(/home/edward/bank1/fiche/Test*)
  if [[ "${#files[@]}" -gt 0 ]] ; then
    echo found one
  else
    echo found none
  fi
)

説明:

  • shopt -s nullglobそのパターンに一致するファイルがない場合、何/home/edward/bank1/fiche/Test*展開されません。(それがないと、そのまま残ります。)
  • ( ... )サブシェルを設定し、shopt -s nullglob「エスケープ」を防ぎます。
  • files=(/home/edward/bank1/fiche/Test*)ファイルリストを。という名前の配列に配置しますfiles。(これはサブシェル内にのみあることに注意してくださいfiles。サブシェルが終了した後はアクセスできません。)
  • "${#files[@]}"この配列の要素の数です。

後続の質問に対処するために編集されました(「これらのファイルにデータが含まれていて、ゼロバイトファイルではないことも確認する必要がある場合はどうなりますか?」):

このバージョンでは、-s(質問で行ったように)を使用する必要があります。これは、ファイルの存在もテストするため、使用する意味はありshopt -s nullglobません。パターンに一致するファイルがない場合-s、パターンはfalseになります。したがって、次のように書くことができます。

(
  found_nonempty=''
  for file in /home/edward/bank1/fiche/Test* ; do
    if [[ -s "$file" ]] ; then
      found_nonempty=1
    fi
  done
  if [[ "$found_nonempty" ]] ; then
    echo found one
  else
    echo found none
  fi
)

(ここでは、「逃げる」の( ... )を防ぎます。)filefound_file

于 2013-03-09T00:24:06.377 に答える
3

あなたは一行でそれを行うことができます:

ls /home/edward/bank1/fiche/Test* >/dev/null 2>&1 && echo "found one" || echo "found none"

それが何であるかを理解するには、コマンドを分解し、ブール論理の基本的な認識を持っている必要があります。

bashのmanページから直接:

[...]
expression1 && expression2
     True if both expression1 and expression2 are true.
expression1 || expression2
     True if either expression1 or expression2 is true.
[...]

シェル(および一般的にUNIXの世界)では、ブール値trueは、ステータス0で終了するプログラムです。

lsパターンをリストしようとします。成功した場合(パターンが存在することを意味します)、それ以外の場合はステータス0、2で終了します(詳細については、lsのマニュアルページを参照してください)。

私たちの場合、実際には3つの式があります。わかりやすくするために、括弧を付けます。ただし、これらは&&優先されるため、必要ありません||

 (expression1 && expression2) || expression3

したがって、expression1がtrueの場合(つまりls、パターンが見つかった場合)、expression2を評価します(これは単なるエコーであり、ステータス0で終了します)。この場合、の左側のサイトにあるもの||はすでに真であり、右側にあるものを評価しようとするとリソースの浪費になるため、expression3は評価されません。

それ以外の場合、expression1がfalseの場合、expression2は評価されませんが、この場合、expression3は評価されます。

于 2013-03-09T00:59:54.373 に答える
1
for entry in "/home/loc/etc/"/*
do

   if [ -s /home/loc/etc/$entry ]
   then
       echo "$entry File is available"
   else
       echo "$entry File is not available"
fi
done

Hope it helps
于 2014-01-29T09:13:34.163 に答える
0

次のスクリプトは、そのスクリプトが指定された変数に存在する場合にプロセスに移動するのに役立ちます。

cat > waitfor.csh

    #!/bin/csh

    while !( -e $1 )

    sleep 10m

    end

ctrl+D

これ-eはファイルを操作するためのものです。

$1はシェル変数であり、

10分間寝る

あなたはスクリプトを実行することができます./waitfor.csh ./temp ; echo "the file exits"

于 2013-07-25T04:43:23.230 に答える
-1

ワイルドカードは、引用符で囲まれた文字列内では展開されません。また、ワイルドカードが展開されると、一致するものがない場合はそのまま返され、空の文字列に展開されません。試す:

output="$(ls home/edward/bank1/fiche/Test* 2>/dev/null)"
if [ -n "$output" ]
then echo "Found one"
else echo "Found none"
fi

ワイルドカードがファイル名に展開されている場合は、lsそれらを上にリストしstdoutます。そうしないと、エラーが表示されstderr、stdout には何も出力されません。の内容はstdoutに割り当てられoutputます。

if [ -n "$output" ]$output何かが含まれているかどうかをテストします。

これを書く別の方法は次のようになります。

if [ $(ls home/edward/bank1/fiche/Test* 2>/dev/null | wc -l) -gt 0 ]
于 2013-03-09T00:23:19.203 に答える