0

以下のスクリプトを使用して、1日より古いファイルを他のディレクトリに移動していますが、echo正常に機能しているかどうかをステートメントで確認していました。

    for i in `ls -lhrt | grep TRACK`
    do
     for j in `$i | awk '{print $7}'`
     do
      if [[ $j -lt $((`date |  awk '{print $3}'` - 1)) ]];
       then echo $j less than $((`date |  awk '{print $3}'` - 1))
      fi
     done
    done

しかし、いくつかのエラーが表示され、スクリプトが正常に機能していません。を実行すると、正常ls -lhrt | grep TRACK | awk '{print $7}'に動作し、日付(数値フィールド)が返されます。

次のようにスクリプトを変更した場合:

    for i in `ls -lhrt | grep TRACK | awk '{print $7}'`
    do 
     if [[ $i -lt $((`date |  awk '{print $3}'` - 1)) ]]; 
      then echo $i less than $((`date |  awk '{print $3}'` - 1))
     fi
    done

それでも問題なく動作します。

元のスクリプトで欠落している正確なロジックは何ですか?

4

3 に答える 3

2

あなたのスクリプトは、最初の for ループ ( for i in ...) が行を反復するという仮定に基づいて動作しますが、その仮定は間違っています。ループの本体にを追加するecho "$i"と、行ではなく単語で動作することがわかります。

次のエラーはすでに指摘されており、その行にある

for j in `$i | awk '{print $7}'`

スクリプトは、変数 $i の内容を実行しようとします。echo次のように、ここにコマンドを追加します。

for j in `echo $i ...

しかしもちろん、これで問題が解決するわけではありません。 $i にはすでに単一の単語が含まれており、 awk が出力できる 7 番目の単語がないためです。

簡単な解決策 (を使用しないことを主張する場合find) は、実際に既に自分で書いたものです。

for i in `ls -lhrt | grep TRACK | awk '{print $7}'`

ただし、両方のループを維持したい場合は、スクリプト内の特殊変数 IFS (内部フィールド セパレータ) を次のように変更できます。

#!/bin/bash

OIFS="$IFS"
IFS="
"
for i in `ls -lhrt` ; do
  IFS="$OIFS"
  echo ">>$i<<"
  for j in `echo $i|awk '{print $7}'` ; do
    echo ">>$j<<"
  done
done

の行には、代入が単一の次の行で終了したIFS="後、何も含まれていないため、IFS 特殊変数に改行文字が割り当てられます。スクリプトでできるだけ早く IFS を復元してください。(そうしないと、スペースが単語を区切らなくなるため、シェルから非常に紛らわしい動作が発生します...)""

PS: 新しい月が始まるたびにスクリプトが失敗することをご存知ですか?

PPS: スクリプトが現在のロケールに依存していることをご存知ですか? 私の PC では、この時期の行の 7 番目の単語は「Dez」なのでLANG=C、スクリプトを実行するときに を追加する必要がありました。

于 2012-12-17T00:00:44.873 に答える
0

あなたの更新を見たところ

$i | ...

の値が何であれ、呼び出される実行可能ファイルを実行しようとします$i。あなたの場合、これは $i = 1、2、および 3 で機能し (ただし、必要なことは実行しません)、それ以外の場合は失敗します。

その名前で実行可能ファイルを実行するのではなく、パイプ内の次のプロセスに文字列を送信したい。あなたがする必要があります

echo $i | ...
于 2012-12-16T14:33:12.067 に答える