如何在 bash 中循环包含通配符的目录列表



假设我有一个包含数十年子目录的目录:

$ ls -d /very/long/path/*/
adir1/ adir2/ b2dir/ b3dir/ k101/ k102/ k103/ k104/ k220/ k221/ k222/ etc

我想遍历一系列目录,这些目录将根据用户给出的答案"动态"定义,并且它将包含通配符。例如(不起作用的代码(:

$ cat my_script.sh
DATADIR="/very/long/path"
echo -n "Select dirs to involve: "
read dirlist
for DIR in "$dirlist"; do
  echo $DATADIR/$DIR 
  [do stuff]
  ...
done

期望的是以下内容:

$ ./my_script.sh
Select dirs to involve: a* k10?
/very/long/path/adir1
/very/long/path/adir2
/very/long/path/k101
/very/long/path/k102
/very/long/path/k103
/very/long/path/k104

有什么提示吗?

不确定这是否会遇到问题,但试一试:

DATADIR="/very/long/path"
read -r -p "Select dirs to involve: " -a dirs
cd $DATADIR
for dir in ${dirs[@]}
do
    echo "$dir"
done

将数组保留为不带引号的数组允许 glob 扩展。

更新:双循环以允许使用目录位置

DATADIR="/very/long/path"
read -r -p "Select dirs to involve: " -a dirs
for item in "${dirs[@]}"
do
  for dir in "$DATADIR/"$item
  do
    echo "$dir"
  done
done

一个潜在的解决方案是使用 find

#!/bin/bash
DATADIR="/very/long/path"
echo -n "Select matching expression: "
IFS= read -r dirlist
while IFS read -r -d '' DIR; do
  echo "$DIR"
  [do stuff]
  ...
done < <(find "$DATADIR" -path "$dirlist" -print0)

我建议您阅读 find 的手册页,因为匹配会吞噬斜杠,并且可能不会像您习惯的外壳通配那样表现。

请注意,使用 -print0read -d'' 是确保处理名称有趣(空格、换行符(的文件没有问题的方法。

如果您希望能够同时处理多个表达式输入,则必须执行以下操作:

#!/bin/bash
DATADIR="/very/long/path"
echo -n "Select matching expression: "
IFS= read -r -a dirlist_array
for dirlist in "${dirlist_array[@]}" ; do
  while IFS read -r -d '' DIR; do
    echo "$DIR"
    [do stuff]
    ...
  done < <(find "$DATADIR" -path "$dirlist" -print0)
done

最新更新