サブディレクトリを表示するときにディレクトリをスキップする

サブディレクトリを表示するときにディレクトリをスキップする

次のサブフォルダがあるディレクトリがあります/u01/oracle/folders

[root@ricusesasctl01vm tax_receipts]# ls -ltr
total 64
drwxr-xr-x 5 OICDev1 oic 4096 Mar  1  2021 Argentina
drwxr-xr-x 5 OICDev1 oic 4096 Mar  1  2021 Brazil
drwxr-xr-x 3 OICDev1 oic 4096 Mar  1  2021 completed
drwxr-xr-x 3 OICDev1 oic 4096 Mar  1  2021 duplicate
drwxr-xr-x 5 OICDev1 oic 4096 Mar  1  2021 EAO
drwxr-xr-x 3 OICDev1 oic 4096 Mar  1  2021 errored
drwxr-xr-x 5 OICDev1 oic 4096 Mar  1  2021 Japan
drwxr-xr-x 5 OICDev1 oic 4096 Mar  1  2021 Korea
drwxr-xr-x 5 OICDev1 oic 4096 Mar  1  2021 SAO
drwxr-xr-x 5 OICDev1 oic 4096 Mar  1  2021 SPPO
drwxr-xr-x 3 OICDev1 oic 4096 Mar  1  2021 temp
drwxr-xr-x 4 OICDev1 oic 4096 Mar  1  2021 template
drwxr-xr-x 3 OICDev1 oic 4096 Mar  1  2021 template2
drwxr-xr-x 5 OICDev1 oic 4096 Mar  1  2021 WHQ
drwxr-xr-x 5 OICDev1 oic 4096 May 10  2021 Canada
drwxr-xr-x 3 OICDev1 oic 4096 Jun  8  2021 canada

シェルスクリプトでは

SourceDirectory="/u01/oracle/folders"
TargetDirectory=/u01/oracle/folders"

値の場合は、$SourceDirectorySAOを除くすべてのサブフォルダを一覧表示したいと思います。

ループでこのコマンドを使用する

#100 Loop through each directory (e.g. brazil, canada, uk)
#
for EachDir in "$SourceDirectory"*;
do
 strFiles=""
 echo "Current Directory is $EachDir"

私は試した:

SourceDirectory=$(find /u01/oracle/folders -maxdepth 1 -type d \( ! -name SAO \))

ディレクトリSAOをスキップしますが、出力は長いリストです。この文字列をディレクトリに分割するにはどうすればよいですか?

例:

[root@ricusesasctl01vm tax_receipts]# SourceDirectory=$(find /u01/oracle/folders -maxdepth 1 -type d \( ! -name SAO \))
[root@ricusesasctl01vm tax_receipts]# echo $SourceDirectory
/u01/oracle/folders /u01/oracle/folders/duplicate /u01/oracle/folders/Brazil /u01/oracle/folders/completed /u01/oracle/folders/template2 /u01/oracle/folders/Canada /u01/oracle/folders/SPPO /u01/oracle/folders/template /u01/oracle/folders/WHQ /u01/oracle/folders/EAO /u01/oracle/folders/errored /u01/oracle/folders/Korea /u01/oracle/folders/Japan /u01/oracle/folders/Argentina /u01/oracle/folders/temp /u01/oracle/folders/canada

答え1

find /u01/oracle/folders -maxdepth 1 -type d \( ! -name SAO \) | while read SourceDirectory
do
  echo "$SourceDirectory"
  ls "$SourceDirectory"
done

答え2

SAO単純なシェルループでこのディレクトリを簡単にスキップできます。

SourceDirectory=/u01/oracle/folders

for dirpath in "$SourceDirectory"/*/; do
    case $dirpath in
        */SAO/) continue ;;
    esac

    # Process "$dirpath" in whatever way is needed.
done

を使用すると、次のように置き換えるbashことができます。case ... esac

[[ $dirpath == */SAO/ ]] && continue

どちらの場合も、このコードはファイル名ワイルドカードパターンテストを使用して、文字列が一致していることを$dirpath確認し*/SAO/、リテラル文字列で終わっていることを確認します/SAO/

別のアプローチbashは、ループ内で拡張されたグローブパターンを使用することです。

shopt -s extglob

SourceDirectory=/u01/oracle/folders

for dirpath in "$SourceDirectory"/!(SAO)/; do
    # Process "$dirpath" in whatever way is needed.
done

ループに使用されるパターンは、名前付き$SourceDirectoryディレクトリを除くすべてのディレクトリと一致しますSAObashシェルで拡張ワイルドカードモードを使用するには、そのモードを有効にする必要がありますshopt -s extglob

findスキップしたいディレクトリが何であるかを正確に知っているので、ここでは使用しません。

感じたら本当に必要これを行うには、find次のことをお勧めします。

SourceDirectory=/u01/oracle/folders

find "$SourceDirectory" ! -path "$SourceDirectory" -prune \
    -type d ! -name SOA -exec sh -c '
    for dirpath do
        # Process "$dirpath" in whatever way is needed.
    done' sh {} +

またはGNUを使用してくださいfind

SourceDirectory=/u01/oracle/folders

find "$SourceDirectory" -mindepth 1 -maxdepth 1 \
    -type d ! -name SOA -exec sh -c '
    for dirpath do
        # Process "$dirpath" in whatever way is needed.
    done' sh {} +

findこれは反復する文字列ジェネレータとして使用されます。この文字列は、$SourceDirectoryこのディレクトリを除くすべてのディレクトリのパス名ですSOA

実行する処理は、sh -cコマンドラインで提供されているインラインスクリプトを介して行われます。

関連情報