我有一个目录如下
-rw-r--r-- 1 ualaoip2 mcm1 1073233 Sep 30 12:40 database.260.4-0.tar.gz
-rw-r--r-- 1 ualaoip2 mcm1 502373963 Sep 30 12:40 database.260.4-1.tar.gz
-rw-r--r-- 1 ualaoip2 mcm1 880379753 Sep 30 12:40 database.260.4-2.tar.gz
drwxr-xr-x 2 ualaoip2 mcm1 4096 Sep 30 13:41 db0file
drwxr-xr-x 2 ualaoip2 mcm1 4096 Sep 30 13:41 db1file
drwxr-xr-x 2 ualaoip2 mcm1 4096 Sep 30 13:41 db2file
我想将文件移动database...0
到folder0
&c...
这样做的最佳方法是什么?我尝试了各种变体
for i in $(ls fi*) do; mv $i ./folder$i
但他们重命名了一些东西并覆盖了很多我不想要的东西!
我尝试使用的变体
find . -maxdepth 1 -type d -printf '%f\n' | sort /* why is it not sorted?
但无法摆脱 .为当前目录。
我使用 mkdir db{0..7} 创建文件 - 这是最好的方法吗?
我希望能对答案进行几句话的解释 - 不仅仅是猴子看到,猴子做! :-)
答案1
如果您可以依赖文件名格式,则可以使用以下命令:
for i in $(seq 0 2); do mv database*-"$i".tar.gz "db${i}file"/; done
有说明。您的文件似乎具有稳定的格式database*-NUMBER.tar.gz
,并且目录名称中具有相同的编号dbNUMBERfile
。我们可以生成最高的数字(在本例中为 0..2 并为这些数字运行循环。在数据库的情况下,简单$i
就足够了,因为它与-
和接壤.
,但是db$ifile
不起作用,因为没有$ifile
定义变量所以我们必须使用大括号db${i}file
,然后才能$i
正确解决。
答案2
set -o nullglob
for name in database*-*[0-9].tar.gz; do
num=${name##*-}
num=${num%%.*}
[ ! -d "folder$num" ] && mkdir "folder$num"
mv "$name" "folder$num"
done
这将迭代与该database*-*[0-9].tar.gz
模式匹配的所有文件名。
该num
变量将是文件名末尾的数字(该数字可能超过一位数字),它是从文件名中挑选出来的,方法是首先删除从名称到最后一个的所有内容-
,然后删除点和所有内容然后。
如果目标文件夹尚不存在,则会创建它们。
通过设置nullglob
shell 选项为bash
first,如果模式与任何文件名都不匹配,我们可以保证根本不会进入循环。
database*.tar.gz
如果您愿意,您可以更改图案。我使用了稍微复杂的模式来确保循环实际使用的名称的所有组件都存在。