使用 bash 将文件夹名称保存为循环中的变量

Save folder name as variable in a loop using bash

我有多个文件夹,我试图将每个文件夹名称保存为一个变量,供下游循环使用:

for f in TINKER*;
do
    name=$(echo $f | sed 's/TINKER_more([0-9]+)_less([0-9]+)/TINKER__/')
    echo $name
done

文件夹示例:

TINKER_more05_less23
TINKER_more55_less218
TINKER_more23_less03

上面第一个文件夹的情况,我要echo $name输出:TINKER_05_23

出于某种原因,我一直从 echo $name 得到空输出。

有人能帮忙吗?谢谢

POSIX BRE 正则表达式中的 + 匹配文字 + 字符。您需要添加 -E 选项以使 sed 使用 POSIX ERE 语法。

此外,您需要在替换中使用\n,而不是$nperl 使用 $n 替换反向引用语法,但 sed 使用 \n.

所以你需要

sed -E 's/TINKER_more([0-9]+)_less([0-9]+)/TINKER__/'

testing有以上数据时,

fldrs="TINKER_more05_less23 TINKER_more23_less03 TINKER_more55_less218"
for f in $fldrs; do
 name=$(echo "$f" | sed -E 's/TINKER_more([0-9]+)_less([0-9]+)/TINKER__/');
 # OR
 # name=$(sed -E 's/TINKER_more([0-9]+)_less([0-9]+)/TINKER__/' <<< "$f");
 echo "$name"
done

输出为

TINKER_05_23
TINKER_23_03
TINKER_55_218

另外,如果你想纯Bash:

rx='TINKER_more([[:digit:]]+)_less([[:digit:]]+)'
for f in TINKER*; do 
    if [[ "$f" =~ $rx ]]; then
        echo "TINKER_${BASH_REMATCH[1]}_${BASH_REMATCH[2]}"
    fi
done

再次查看 this online demo 产生 TINKER_05_23TINKER_23_03TINKER_55_218

TINKER_more([[:digit:]]+)_less([[:digit:]]+) 正则表达式包含两个用两对非转义括号定义的捕获组,以及 ${BASH_REMATCH[1]} 包含第 1 组的内容,${BASH_REMATCH[2]} 包含第 2 组的值。

使用sed

$ name=$(sed 's/_[^0-9]*\([^_]*\)/_/g' <<< $f)

Bash 有一个 built-in 匹配运算符 =~,因此您不需要 sed。您可以使用纯 Bash 编写代码段,如下所示:

for f in TINKER*; do 
    if [[ $f =~ TINKER_more([0-9]+)_less([0-9]+) ]]; then
        echo TINKER_${BASH_REMATCH[1]}_${BASH_REMATCH[2]}
    fi
done

以上代码将为您发布的文件生成以下输出:

TINKER_05_23
TINKER_23_03
TINKER_55_218