Bash:一部のディレクトリを除くすべてのディレクトリを変数に追加する

Bash:一部のディレクトリを除くすべてのディレクトリを変数に追加する

次の変数にディレクトリを追加したいと思います。

   WATCHED_DIR="\
      someDir_1/* \
      someDir_2/* \
      someDir_3/* \

各ディレクトリには多くのサブディレクトリがあり、ほとんどの場合は問題ありません。しかし、今除外したいサブディレクトリのリストを含む変数を作成したいと思います。

たとえば、

EXCLUDED_DIRS:"\
        someDir_2/docs/ \
        someDir_3/docs/ "

除外部分をどのようにすべきかわかりません。

更新:私が達成したいことを明確にするために、次のコードスニペットを使用するとよりよく理解できます。

# Add directories to watch
WATCH_FILES="\
.github/workflows/ci-tests/Examples_tests \
Examples/MCU1/BLE \
Examples/MCU1/Bootloader \
Libraries/libs.mk \
Libraries/Cordio/* \
Libraries/CMSIS/Device/MCU1 \
Libraries/PeriphDrivers/ \\
Libraries/BlePhy/ \
Libraries/Boards/"
#remove unwanted sub-directories
IGNORED_DIRS="\ 
            Libraries/Cordio/docs \
            Libraries/Cordio/controller"

for ignored_dir in $IGNORED_DIRS; do
  # some how remove from watch files
done

WATCH_FILESを印刷すると、Cordio内のすべてのサブディレクトリを取得できますが、削除できて良いと思います。 Cordioから*を削除すると、文字列にサブディレクトリは表示されません。必要な最終結果は、無視されたサブディレクトリを含まないWATCH_FILESを取得することです。

きれいなWATCHファイルのリストを使用してgit diffを実行し、そのWATCHファイルディレクトリに変更されたファイルがあることを確認します。

答え1

すでに言及しているので、bash配列を使用することをお勧めします。また、削除するディレクトリを簡単に識別できるように、連想配列を使用して無視するディレクトリをアーカイブします。results()後で必要に応じて、配列を改行で区切られたリストに縮小できます。

watchedリストが実際の状況と一致するディレクトリでこのコードを実行してくださいignored。これにより、globをLibraries/Cordio/*物理ディレクトリのリストに拡張できます。それ以外の場合は、ワイルドカードと一致するディレクトリのリストを取得できません。これは、ディレクトリセットが認識されないことを意味します。それじゃない除外された。

#!/bin/bash
shopt=$(shopt -p nullglob)    # Save nullglob setting
shopt -s nullglob             # Enable nullglob

# Directories to watch
declare -a watched=(
    .github/workflows/ci-tests/Examples_tests
    Examples/MCU1/BLE
    Examples/MCU1/Bootloader
    Libraries/libs.mk
    Libraries/Cordio/*
    Libraries/CMSIS/Device/MCU1
    Libraries/PeriphDrivers
    Libraries/BlePhy
    Libraries/Boards
)

# Directories to ignore
declare -a ignored=(
    Libraries/Cordio/docs
    Libraries/Cordio/controller
)

# Reset shopt nullglob
$shopt                        # Revert nullglob

# Work starts here

# Create an associative array for ignored()
declare -A aignored=()
for ignore in "${ignored[@]}"; do aignored["${ignore%/}"]=1; done

# Copy the working directory list, skipping entries in ignored()
declare -a results=()
for watch in "${watched[@]}"; do test -v aignored["${watch%/}"] || results+=("${watch%/}"); done

# Print the resulting array, separated by newlines, in sorted order
printf '%s\n' "${results[@]}" | sort

あなたの例の結果です。実際には、およびLibraries/Cordio4 つのディレクトリがあると仮定します。adirectorydocscontrollersomedirectorytokeep

.github/workflows/ci-tests/Examples_tests
Examples/MCU1/BLE
Examples/MCU1/Bootloader
Libraries/BlePhy
Libraries/Boards
Libraries/CMSIS/Device/MCU1
Libraries/Cordio/adirectory
Libraries/Cordio/somedirectorytokeep
Libraries/PeriphDrivers
Libraries/libs.mk

この例(特に最後の例printf | sort)では、ディレクトリ名に改行文字が含まれていないと想定しています。可能であれば、NULLで終わる文字列を使用するか、結果リストを操作できます。

関連情報