我在一个文件夹中有多个文件:
ABA.xy
BEB.xy
ACA.xy
另一个文件夹中具有不同扩展名的相同文件
ABA.rr
BEB.rr
ACA.rr
然后我为每个文件名创建一个文件夹
ABA
BEB
ACA
我想执行以下操作。如果文件带有扩展名.xy
并且.rr
与文件夹同名,则移动到该文件夹。例如
ABA.xy and ABA.rr in ABA
我很熟悉,mv
但我认为在这里我必须编写一个小脚本来做到这一点。
答案1
假设您的文件存储在source
目录中,并且目标文件夹位于dest
以下树中:
$ tree source
source
├── dir1
│ ├── ABA.xy
│ ├── ACA.xy
│ └── BEB.xy
└── dir2
├── ABA.rr
├── ACA.rr
└── BEB.rr
2 directories, 6 files
$ tree dest
dest
├── ABA
├── ACA
└── BEB
3 directories, 0 files
命令如下:
find source -type f -exec sh -c 'noext="${0%.*}"; echo mv '{}' "dest/${noext##*/}/"' {} \;
- 是
source
源目录或指定父目录。 noext="${0%.*}"
删除文件扩展名并将结果保存到noext
变量中。"${noext##*/}"
从变量中删除文件路径部分noext
并拾取唯一的文件名。dest
目录是目标父目录。因此
mv '{}' "dest/${noext##*/}/"'
将当前文件移动到dest/$noext
目录。上述命令的内容
noext
只有文件名,不包含扩展名和路径,指定与当前文件名同名的目标目录。
请注意,此命令用于echo
测试和试运行。如果您确定要做什么,请删除命令echo
前面的mv
以执行实际移动。
答案2
稍微不同的方法使用rename
:
rename 's#.*/(.+)(\.\w+)#mkdir "dest/$1"; "dest/$1/$1$2"#e' source/{a,b}/*
这本质上只是使用正则表达式来转换路径。我们使用一点 Perl(支持rename
)来创建新目录,并在最后重命名移动文件。
它不太聪明。它不会搜索没有对应文件的情况(我们可以搜索并删除只有一个文件的目录),如果有没有扩展名的文件,它可能会爆炸。
$ mkdir -p source/{a,b} dest
$ touch source/a/{ABA,BEB,ACA}.xy
$ touch source/b/{ABA,BEB,ACA}.rr
$ tree
.
├── dest
└── source
├── a
│ ├── ABA.xy
│ ├── ACA.xy
│ └── BEB.xy
└── b
├── ABA.rr
├── ACA.rr
└── BEB.rr
$ rename 's#.*/(.+)(\.\w+)#mkdir "dest/$1"; "dest/$1/$1$2"#e' source/{a,b}/*
$ tree
.
├── dest
│ ├── ABA
│ │ ├── ABA.rr
│ │ └── ABA.xy
│ ├── ACA
│ │ ├── ACA.rr
│ │ └── ACA.xy
│ └── BEB
│ ├── BEB.rr
│ └── BEB.xy
└── source
├── a
└── b