没有脚本范围的 shopt extglob 的全局多个数字
Glob multiple digits without script-wide shopt extglob
我正在编写一个 shell 脚本来遍历某些文件。
for f in $folder-*-something; do
echo $f
done
通常没问题,但我只想 glob 数字 ,所以我不想匹配 $folder-1-2-something
完全符合要求的东西是
#!/usr/bin/env bash
shopt -s extglob
if [ -eq 0 ]; then
for f in $folder-+([[:digit:]])-something; do
echo $f
done
fi
extglob
无法仅在 if
块中打开 - 它 returns syntax error near unexpected token `('
(我在某处阅读了一个简短的摘要,但我可以再也找不到了)。如果那行得通,我可以在完成相关行后 reset it。
问题:我正在扩展的脚本是一个大型开源项目的一部分,我不想在整个 >500 行的脚本中打开选项,因为这可能会干扰其他代码。
我现在倾向于使用 *
-globbing 并跳过不相关的条目。
- 有更好的方法吗?
- 在哪里可以找到有关
shopt
及其怪癖的深入信息?我发现很多网站都在谈论所有选项,但我什至找不到关于为什么将它直接放在 shebang 之后的两行描述。
一种解决方法是将与扩展模式匹配的文件名存储到数组中,然后取消设置 extglob
。之后,必须使用数组,而不是扩展模式:
shopt -s extglob
files=("$folder"-+([[:digit:]])-something)
shopt -u extglob
if [ "" -eq 0 ]; then
for f in "${files[@]}"; do
echo "$f"
done
fi
或者,如果你想恢复状态:
saved_state=$(shopt -p)
shopt -s extglob
files=("$folder"-+([[:digit:]])-something)
eval "$saved_state"
使用 find
而不是 globbing:
find . -regex "./$folder-[0-9]+-something" |
while IFS= read -r f; do
echo "$f"
done
我正在编写一个 shell 脚本来遍历某些文件。
for f in $folder-*-something; do
echo $f
done
通常没问题,但我只想 glob 数字 ,所以我不想匹配 $folder-1-2-something
完全符合要求的东西是
#!/usr/bin/env bash
shopt -s extglob
if [ -eq 0 ]; then
for f in $folder-+([[:digit:]])-something; do
echo $f
done
fi
extglob
无法仅在 if
块中打开 - 它 returns syntax error near unexpected token `('
(我在某处阅读了一个简短的摘要,但我可以再也找不到了)。如果那行得通,我可以在完成相关行后 reset it。
问题:我正在扩展的脚本是一个大型开源项目的一部分,我不想在整个 >500 行的脚本中打开选项,因为这可能会干扰其他代码。
我现在倾向于使用 *
-globbing 并跳过不相关的条目。
- 有更好的方法吗?
- 在哪里可以找到有关
shopt
及其怪癖的深入信息?我发现很多网站都在谈论所有选项,但我什至找不到关于为什么将它直接放在 shebang 之后的两行描述。
一种解决方法是将与扩展模式匹配的文件名存储到数组中,然后取消设置 extglob
。之后,必须使用数组,而不是扩展模式:
shopt -s extglob
files=("$folder"-+([[:digit:]])-something)
shopt -u extglob
if [ "" -eq 0 ]; then
for f in "${files[@]}"; do
echo "$f"
done
fi
或者,如果你想恢复状态:
saved_state=$(shopt -p)
shopt -s extglob
files=("$folder"-+([[:digit:]])-something)
eval "$saved_state"
使用 find
而不是 globbing:
find . -regex "./$folder-[0-9]+-something" |
while IFS= read -r f; do
echo "$f"
done