3

ディレクトリ ツリーは次のようになります。

.
├── A_123
│   └── 123.txt
├── A_456
│   ├── tmp
│   └── tmp.log
└── A_789
    └── 789.txt

3 つのディレクトリ (A_123、A_456、A_789) があります。ディレクトリ名のパターンは:A_{numbers}で、関心のあるファイルは です{numbers}.txt

ファイルが含まれA_{numbers}ていないディレクトリを取得する方法があるかどうか疑問に思っていました。{numbers}.txt上記の例のように、このスクリプトは次を返す必要があります。

./A_456

そのフォルダーにはありA_456ませんが、関連するフォルダーにファイルがあります。456.txtA_123A_789{numbers}.txt

誰でもこれについてアイデアがありますか?ありがとう!

4

4 に答える 4

4

1 つのアプローチを次に示します。

for dir in *;do 
  if [ $(find "$dir" -maxdepth 1 -regex '.*/[0-9][0-9]*\.txt' | wc -l) = 0 ]; then 
    echo $dir
  fi
done
于 2012-10-30T05:21:42.550 に答える
1

A_[0-9] ディレクトリはネストされていないため、ループ内のグロブを使用して簡単にこれを行うことができます。この実装は純粋な bash であり、外部ユーティリティでは生成されません。

for d in A_[0-9]*/; do         # the trailing / causes only directories to be matched
   files=("$d"/[0-9]*.txt)     # populate an array with matching text files
   ((!${#files})) && echo "$d" # echo $d if the array is empty
done

この実装にはいくつかの問題があります。「12ab.txt」などのファイルに一致し、ディレクトリのすべてのファイル名を配列にロードする必要があります。

より正確なファイル名の一致を行う bash の別の方法を次に示します。

re='^[0-9]+[.]txt$'
for d in A_[0-9]*/; do
   for f in *; do
      if [[ -f $f && $f =~ $re ]]; then
         echo "$d"
         break
      fi
   done
done
于 2012-10-30T06:09:01.517 に答える
1

他のいくつかの回答のわずかなバリエーション: bash 拡張パターン マッチングを使用します

shopt -s extglob nullglob
for dir in  A_+([0-9]); do
    files=($dir/+([0-9]).txt)
    (( ${#files[@]} == 0 )) && echo $dir
done
于 2012-10-30T15:18:52.973 に答える
0
for file in *; do
  if [[ "$file" =~ ^A_([0-9]+)$ && ! -f "$file/${BASH_REMATCH[1]}.txt" ]]; then
    echo $file;
  fi
done

使い方:

  1. =~ファイル/フォルダーの名前が「A_」の後に番号が続くことを正規表現 ( に注意) を使用してチェックします。
  2. 同時に、数字をキャプチャして (括弧に注意)、次の場所に格納します。${BASH_REMATCH[1]}
  3. 次に、フォルダに が含まれているかどうかを確認します{number}.txt
  4. そうでない場合は、フォルダーの名前をエコーし​​ます。
于 2012-10-30T13:53:38.457 に答える