获取除数组中的文件以外的所有文件 - Bash

Kan*_*thy 5 shell-script

我需要编写一个一次性的 util,它对给定目录中的所有文件执行一些操作,但对预定义列表中的文件列表执行一些操作。由于给定的列表是预定义的,我将把它硬编码为一个数组。

话虽如此,如何获取不在给定数组中的所有文件的名称?这可以在任何标准的 unix 脚本(bash、awk、perl)中。

Sté*_*las 6

使用bash,您可以执行以下操作:

all=(*)
except=(file1 file2 notme.txt)
only=()
IFS=/
for file in "${all[@]}"; do
  case "/${except[*]}/" in
    (*"/$file/"*) ;;     # do nothing (exclude)
    (*) only+=("$file")  # add to the array
  esac
done
ls -ld -- "${only[@]}"
Run Code Online (Sandbox Code Playgroud)

(这适用于当前目录中的文件,但对于像all=(*/*) except=(foo/bar)我们/用来连接数组元素以进行查找的glob 而言并不可靠)。

它基于这样一个事实,即将"${array[*]}"数组元素与第一个字符$IFS(此处选择为/因为它不能出现在文件名中;NUL 是一个不能出现在文件路径中的字符,但不幸的是bash(与zsh) 的变量中不能有这样的字符)。因此,对于每个文件$all(这里$filefoo作为一个例子),我们做一个case "/file1/file2/notme.txt/" in (*"/foo/"*)检查,如果$file是被排除在外。


Sté*_*las 5

使用zsh以下方法更容易:

except=(file1 file2 notme.txt)
all=(*)
only=(${all:|except})
ls -ld -- $only
Run Code Online (Sandbox Code Playgroud)

助记符${all:|except}:元素$all 酒吧的那些$except

您还可以检查文件是否在$except数组中作为glob 限定符的一部分:

ls -ld -- *.txt(^e:'((except[(Ie)$REPLY]))':)
Run Code Online (Sandbox Code Playgroud)

或者使用一个函数:

in_except() ((except[(Ie)${1-$REPLY}]))
ls -ld -- *.txt(^+in_except)
Run Code Online (Sandbox Code Playgroud)