【发布时间】:2018-12-20 19:16:02
【问题描述】:
我有一个进程在大型文件系统上从一天到另一天审核文件。我想通过使用要排除的目录列表来排除一些目录。我可以这样做,但如果排除目录的名称中有空格,我会遇到麻烦。
为简单起见,我只列出四个子目录,但实际上我要搜索与排除的目录要多得多。也有可能添加一个新目录并且我想自动包含新目录,因此排除列表与使用包含列表。
base_dir/
├── sub_dir1
├── sub_dir2
├── sub dir3
└── sub_dir4
我有一个 shell 脚本和一个排除列表
$ cat exclude.txt
sub_dir2
sub dir3
shell 脚本使用find 和printf 以及awk 和sort 来获取要审核的目录列表。
$ find ./base_dir -maxdepth 1 -type d $(printf "! -iname %s " $(cat exclude.txt)) | awk -F/ '{print $NF}' | sort
sub_dir1
sub dir3
sub_dir4
正如您可能猜到并在上面看到的那样,除了它没有忽略sub dir3 之外,它是有效的。我在排除列表中尝试了一些双引号组合,并使用%q vs %s vs %a,但似乎找不到正确的组合。
我想要的输出是
sub_dir1
sub_dir4
我意识到我可以这样做:
find ./base_dir -maxdepth 1 -type d \
! -iname "sub dir3" $(printf "! -iname %s " $(cat exclude.txt)) \
| awk -F/ '{print $NF}' | sort
并获得我预期的输出,但我只想使用exclude.txt 列表。
编辑 在阅读了一些回复后,我尝试使用数组并认为它会起作用,现在我更加难以理解为什么这个选项不起作用。 printf 似乎会生成一个字符串,如果我将它严格输入到命令行中,它会起作用,但是当尝试将它作为单行符运行时仍然会给我错误。
$cat exclude.txt
base_dir
sub_dir2
"sub dir3"
$ mapfile -t exclude < exclude.txt
$printf "! -iname %s " "${exclude[@]}"
! -iname base_dir ! -iname sub_dir2 ! -iname "sub dir3"
$find ./base_dir -maxdepth 1 -type d $(printf "! -iname %s " "${exclude[@]}")
find: paths must precede expression: dir3"
$ find ./base_dir -maxdepth 1 -type d ! -iname base_dir ! -iname sub_dir2 ! -iname "sub dir3"
./base_dir/sub_dir1
./base_dir/sub_dir4
【问题讨论】:
-
这是一个猜测:在您的排除列表中,您是否尝试过使用反斜杠而不是使用引号?
sub\ dir3. -
是的,对不起,没有提到,我也试过文件中的反斜杠
-
对于编辑,请参阅stackoverflow.com/questions/51307638/… 询问几乎所有内容。
-
您评论中的链接是指向该主题的链接....您是要发布另一个链接吗?