大括号扩展内的路径名扩展

大括号扩展内的路径名扩展

以下代码正在运行:

mkdir /home/karan/{Pictures,Public}/yo

上面的行在名为和yo的目录中创建一个命名目录。但是,当我使用下面的代码时,出现错误:PublicPictures

mkdir /home/karan/{P*}/yo
error: cannot create directory ‘/home/karan/{P*}/123’

我知道星号没有扩展到给定的目录,但无法理解原因。我也没有使用任何引用机制来抑制星号扩展。

答案1

使用zsh,您可以执行以下操作:

(){ mkdir $^@/yo; } /home/karan/P*(/)

(其中$^array打开rcexpandparam(for rc-style 数组扩展)仅用于扩展$array,以及该 glob 的扩展(此处使用/glob 限定符来限制类型的文件目录$@)通过使用匿名函数将其转换为数组)。

或者你可以这样做:

mkdir /home/karan/P*(/e:REPLY+=/yo:)

(使用e评估 glob 限定符将 a 附加/yo到匹配文件)。

或者:

set -o histsubstpattern
mkdir /home/karan/P*(/:s:%:/yo)

(在这种情况下使用:s/string/replacement/csh-style 修饰符进行添加/yo。对于histsubstpatternstring被解释为模式,并且像 ksh 中的 一样${var/pattern/replacement},前导%意味着该模式锚定在主题的末尾)

rc或衍生物:

dirs = ( /home/karan/P*/ )
mkdir $dirs^yo

es,其中一个rc派生函数也具有与zsh上面类似的匿名函数,但语法不同:

@ {mkdir $*^yo} /home/karan/P*/

fish

set dirs /home/karan/P*/
mkdir ${dirs}yo

使用 ksh93 或 bash(或 zsh),您始终可以执行以下操作:

dirs=(/home/karan/P*/)
mkdir "${dirs[@]/%/yo}"

或者使用任何 shell 和 GNU xargs

printf '%syo\0' /home/karan/P*/ | xargs -r0 mkdir

(请注意, 的扩展(与'sP*/相对)还将包括到目录的符号链接。在 中,将glob 限定符替换为if 它实际上是您想要的)。zshP*(/)zsh/-/

答案2

Bash 的手册:

要展开大括号的模式采用可选前导码的形式,后跟一系列逗号分隔的字符串或一对大括号之间的序列表达式

你的尝试

  1. mkdir /home/karan/{P*}/123
    

不是大括号扩展的有效形式,因为大括号内没有逗号也没有序列。因此,你得到的正是你所给予的/home/karan/{P*}/123

  1. mkdir /home/karan/{P*,}/123
    

是一个大括号扩展(注意逗号),它将尝试创建/home/karan/P*/123/home/karan//123目录。请注意,仍然P*没有通过文件名扩展进行扩展,因为还没有.../Pictures/123.../Public/123目录。换句话说,当没有匹配时,文件名扩展不会发生。

无论如何,如(1)所示,对单个元素使用大括号扩展是没有意义的,它就像一个人的跷跷板。直接的

  1. mkdir /home/karan/P*/123
    

会因为同样的原因失败,没有匹配。

我没有看到在您的特定情况下逃避拼写路径的好方法,但如果有许多匹配的目录或路径,for 循环将节省您的击键次数。

for d in /home/karan/P*/; do mkdir "$d"yo; done

相关内容