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。这将允许 globLibraries/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/Cordio实际上包含四个目录: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 结尾的字符串或以其他方式处理结果列表。

相关内容