我在包含许多文件夹的目录中:
At_5.2000_displacement
At_-6.4000_displacement
At_2nd_-4.3000_displacement
At_2nd_2.2000_displacement
我正在编写一个bash脚本cd
- 每个类型的文件夹:
At_X.XXXX_displacement
即,我想
cd At_5.2000_displacement
和
cd At_-6.4000_displacement
个文件夹。这省略了类型的文件夹:
At_2nd_X.XXXX_displacement
我的尝试(已编辑):
我找到了产生目标文件夹名称的reg-ex,如下所示:
At_-\?[0-9][.].*displacement
产生:
At_5.2000_displacement
At_-6.4000_displacement
现在,在bash
脚本中,每次我都这样做:
cd /path_to_the_folders/At_-\?[0-9][.].*displacement
无法访问每个文件夹,因为收到的错误是:
trial_cding.sh: line 11: cd: /path_to_the_folders/At_-?[0-9][.].*displacement: No such file or directory
如何让行cd /path_to_the_folders/At_-\?[0-9][.].*displacement
生效?
根据我的理解,@ dawg通过if
语句(不使用快捷方式)的答案实现如下:
for pn in *; do
if [[ ! -d "$pn" && $pn =~ At_[0-9.-]*_displacement ]]
then
echo No desired directory found
else
continue
cd $pn
pwd
cd -
fi
done
但是,这不会返回任何结果。我在这里弄错了什么?
此外,我不太确定如何在cd $pn
中使用括号以避免返回
关于[0-9.-]
匹配......
最后我们正在寻找正或负十进制数。
换句话说,我们正在寻找从( - )0到( - )9的任何数字,然后是.
这让我觉得[-0-9.]
是最直观的指示。
令人惊讶的是,碰巧以下三个也匹配:
[0-9.-]
[0-9-.]
[-.0-9]
请查看我显示比赛的https://regex101.com/r/G3fXo5/1。这让我觉得[ ]
内的匹配条件非常广泛。
所以,我试试[.-0-9]
我得不到匹配的结果。为什么会这样?内部匹配[ ]
背后的规则是什么?
答案 0 :(得分:3)
假设X
只能是一个数字,你可以使用扩展的globbing:
shopt -s extglob nullglob
for folder in At_?(-)[0-9].[0-9][0-9][0-9][0-9]_displacement/; do
#do stuff here
echo "$folder"
done
shopt -s nullglob
是为了确保在没有与您的模式匹配的文件时不会循环shopt -s extglob
启用扩展的全局?(-)
匹配-
零次或一次匹配。在扩展的全局中,修饰符出现在(pattern)
之前。请参阅:Pattern matching 此方法的优点是仅在您真正想要的文件夹上循环。无需额外检查。
答案 1 :(得分:1)
假设:
$ ls -l
total 0
drwxr-xr-x 2 dawg wheel 68 Jan 4 10:42 At_-6.4000_displacement
drwxr-xr-x 2 dawg wheel 68 Jan 4 10:42 At_2nd_-4.3000_displacement
drwxr-xr-x 2 dawg wheel 68 Jan 4 10:42 At_2nd_2.2000_displacement
drwxr-xr-x 2 dawg wheel 68 Jan 4 10:42 At_5.2000_displacement
-rw-r--r-- 1 dawg wheel 0 Jan 4 10:51 file
你可以使用常规的Bash glob *
,测试看每个glob是一个目录-d
(与其他一些OS对象相比),然后使用Bash正则表达式测试字符串:
for pn in *; do # You could use At_*_displacement glob to narrow if desired...
[[ -d "$pn" && $pn =~ At_[0-9.-]*_displacement ]] || continue
# ^^ a directory?
# ^^ and
# ^ ^^ match this regex
# OR ^
# continue (skip) to the next glob pattern in loop ^^
# do you Bash thing on this directory...
# you can cd "$pn" or operate on the directory directly
# ( use parenthesis for a sub shell and you don't need to cd back )
echo "$pn"
done
打印:
At_-6.4000_displacement
At_5.2000_displacement
您还可以将find
与适当的深度限定符和正则表达式一起使用:
$ find . -type d -maxdepth 1 -regex '\./At_[0-9.-]*_displacement'
./At_-6.4000_displacement
./At_5.2000_displacement
然后使用exec {}
或xargs
或将该输出反馈给Bash while
循环。
上次编辑,如下所示:
for pn in *; do
if [[ -d "$pn" && $pn =~ At_[0-9.-]*_displacement ]]
then
( # the ( creates a subshell so no need to cd back...
echo "Found \"$pn\"! Touching it!"
cd "$pn" # USE QUOTES!
# you are now in that sub directory
touch "dawg was here!" # create a file in the directory...
)
# exit sub shell -- back to the original directory
else
echo "\"$pn\" is not what we are looking for..."
fi
done
请务必在Bash扩展中使用“$ quotes”。
答案 2 :(得分:0)
cd
一次不能更改为多个目录。你需要一个for循环。
这个怎么样:
for i in `ls | grep "^At_-\?[0-9][.].*displacement$"`; do
cd $i
# do what needs to be done
done