简体   繁体   English

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

[英]How to loop over a list of directories containing wildcards in bash?

Assuming that I have a directory which contains decades of subdirectories: 假设我有一个包含数十年子目录的目录:

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

I would like to loop over a selection of directories which will be defined "dynamically" based on the answer given by the user and it will contain wildcards. 我想循环选择一些目录,这些目录将根据用户给出的答案“动态”定义,并且它将包含通配符。 For example (the code that doesn't work): 例如(代码不起作用):

$ 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

What would be desired is the following: 可能需要的是以下内容:

$ ./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

Any hint? 任何提示?

One potential solution is to use find : 一个可能的解决方案是使用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)

I would advise that you read the manpage of find , as matching will eat up slashes, and might not behave as you are used to with shell globbing. 我建议您阅读find的联机帮助页,因为匹配会占用斜线,并且可能不像您习惯使用shell globbing那样。

Please note that using the -print0 and read -d'' is a way to make sure files with funny names (whitespace, newlines) are handled without issues. 请注意,使用-print0read -d''可以确保处理具有有趣名称(空格,换行符)的文件而不会出现问题。

If you want to be able to handle several expressions input at the same time, you would have to do something like this : 如果您希望能够同时处理多个表达式输入,则必须执行以下操作:

#!/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

Not sure if this would run into problems, but give it a whirl: 不确定这是否会遇到问题,但要给它一个旋转:

DATADIR="/very/long/path"

read -r -p "Select dirs to involve: " -a dirs

cd $DATADIR

for dir in ${dirs[@]}
do
    echo "$dir"
done

Leaving the array unquoted allows for the globs to expand. 让阵列不加引号可以使球体扩展。

UPDATE: Dual loop to allow for using directory location 更新:双循环允许使用目录位置

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM