如何遍历 bash 中包含通配符的目录列表?
How to loop over a list of directories containing wildcards in bash?
假设我有一个包含数十个子目录的目录:
$ ls -d /very/long/path/*/
adir1/ adir2/ b2dir/ b3dir/ k101/ k102/ k103/ k104/ k220/ k221/ k222/ etc
我想遍历一系列目录,这些目录将根据用户给出的答案 "dynamically" 定义,并且包含通配符。例如(不起作用的代码):
$ 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
有什么提示吗?
一个可能的解决方案是使用 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
的联机帮助页,因为匹配会消耗斜杠,并且可能不会像您习惯的 shell globbing 那样表现。
请注意,使用 -print0
和 read -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
不确定这是否会 运行 出现问题,但试一试:
DATADIR="/very/long/path"
read -r -p "Select dirs to involve: " -a dirs
cd $DATADIR
for dir in ${dirs[@]}
do
echo "$dir"
done
不引用数组允许 globs 扩展。
更新:双循环允许使用目录位置
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
假设我有一个包含数十个子目录的目录:
$ ls -d /very/long/path/*/
adir1/ adir2/ b2dir/ b3dir/ k101/ k102/ k103/ k104/ k220/ k221/ k222/ etc
我想遍历一系列目录,这些目录将根据用户给出的答案 "dynamically" 定义,并且包含通配符。例如(不起作用的代码):
$ 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
有什么提示吗?
一个可能的解决方案是使用 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
的联机帮助页,因为匹配会消耗斜杠,并且可能不会像您习惯的 shell globbing 那样表现。
请注意,使用 -print0
和 read -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
不确定这是否会 运行 出现问题,但试一试:
DATADIR="/very/long/path"
read -r -p "Select dirs to involve: " -a dirs
cd $DATADIR
for dir in ${dirs[@]}
do
echo "$dir"
done
不引用数组允许 globs 扩展。
更新:双循环允许使用目录位置
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