BASH通配符扩展

我不太确定如何解释这个,也许这就是为什么我找不到任何东西,但是我想在命令中重用通配符列举的值。 这可能吗?

场景:
$ ls /dir
1 2 3
$ ls /dir
1 2 3
/目录的内容是目录1,2和3。

$ cp /dir/*/file . 将文件从/ dir / 1 / dir / 2和/ dir / 3复制到这里。

我想要做的是将文件复制到基于通配符扩展的新目标名称。

$ cp /dir/*/file ???-file会导致/ dir / * /文件被复制到1个文件,2个文件和3个文件。 我想不出来的是??? 部分告诉BASH我想使用通配符扩展值。

在目标networking中使用通配符cp错误:cp:target`* -file'不是目录。 在这里可以使用bash中的其他东西吗?

find命令有{}-exec一起使用,这与我在上面查找的类似。

 ls /dir |while read dirname; do cp -v /dir/"$dirname"/file "$dirname"-file ; done 

我的第一个想法是你可能使这个问题太复杂了。 但是,这是可以解决的。

你可以用一个疯狂的bash循环做这样的事情:

 for i in /dir/*/file do j=${i%/file} k=${j#/dir/} cp $i %k-file done 

它使用几个bash string运算符来提取源目录的编号。

我保证有更好的方法来做到这一点,这正是我想到的。

 zsh% autoload zmv # should be done for you, noting it just in case zsh% zmv -C '(*)/file' '$1-file' 

zmv是一个shell函数,通常通过alias mmv='noglob zmv -W'来使用,这样可以更轻松地进行调用,但是在这种情况下,您需要定期使用,再加上-C来复制而不是移动。

正如Phil所说的,你需要遍历扩展通配符的元素; 提取你关心的位(在你的例子中,目录下的目录的名称/),然后对提取的值进行操作。

我有一个不同的快速和黑客的方式来做到这一点。 显而易见的错误是,如果文件名中有空格,这将会中断,但这不是唯一的错误。

 andromeda:tmp polleyj$ find dir/ ?-file dir/ dir//1 dir//1/a dir//1/b dir//1/c dir//2 dir//2/d dir//2/e dir//2/f dir//3 dir//3/g dir//3/h dir//3/i 1-file 2-file 3-file andromeda:tmp polleyj$ for f in dir/*; do > i=$(basename $f) > mv dir/${i}/* ${i}-file/ > done andromeda:tmp polleyj$ find dir/ ?-file dir/ dir//1 dir//2 dir//3 1-file 1-file/a 1-file/b 1-file/c 2-file 2-file/d 2-file/e 2-file/f 3-file 3-file/g 3-file/h 3-file/i andromeda:tmp polleyj$ 

在大多数发行版(使用util-linux的重命名 ):

 rename /file -file /dir/*/file 

在Debian和Ubuntu上(指责Debian):

 rename.ul /file -file /dir/*/file 

或者使用Perl的重命名(在Debian和Ubuntu上,我不知道在哪里可以find它在其他发行版):

 rename 's,(\d+)/file,$1-file,' */file 

这不是很漂亮:

 find -type f -exec sh -c 'cp "{}" "$(basename "$(dirname "{}")")-$(basename "{}")"' \; 

如果我明白了, mcp正在做你想做的事情。

提示:mcp属于mmv包。

你的情况:

 $树
 。
 ├──dir
 │├──1
 ││└──foo
 │├──2
 ││└──吧
 │└──3
 │└──巴兹
 └──dst

 5个目录,3个文件

解决scheme:

 $ mcp -v'dir / * / *''dst /#1-#2'
 dir / 1 / foo  - > dst / 1-foo:完成
 dir / 2 / bar  - > dst / 2-bar:完成
 dir / 3 / baz  - > dst / 3-baz:完成

 $树
 。
 ├──dir
 │├──1
 ││└──foo
 │├──2
 ││└──吧
 │└──3
 │└──巴兹
 └──dst
     ├──1-foo
     ├──2杆
     └──3-baz

 5个目录,6个文件

我认为这应该大部分是不言自明的

这里发生的是mcp 一个和一个参数。 from参数可以包含与一组文件匹配的shell通配符模式(*,?)。 这些匹配在#1,#2,#3等有序的方式中被反向引用。