目前正在进行一些清理工作,并且我正在努力相应地重命名我的文件。
我现在有类似这样的(名称只是占位符,除了 alpha 和 beta 之外还有很多):
└── Project/
├── alpha/
│ ├── alpha1/
│ │ ├── file1
│ │ └── file2
│ └── alpha2/
│ ├── file1
│ └── file2
└── beta/
├── beta1/
│ ├── file1
│ └── file2
└── beta2/
├── file1
└── file2
并希望它是这样的:
└── Project/
├── alpha/
│ ├── alpha1_file1
│ ├── alpha1_file2
│ ├── alpha2_file1
│ └── alpha2_file2
└── beta/
├── beta1_file1
├── beta1_file2
├── beta2_file1
└── beta2_file2
我该如何实现这一点?非常感谢您的帮助,在此先行致谢!
答案1
使用bash
(Ubuntu 中的默认用户 shell)shell 参数扩展,可以从Project
目录内完成,例如:
for d in */*/
do
for f in "${d}"*
do
[[ -f "${f}" ]] && echo mv -nv -- "${f}" "${f%/*}_${f##*/}"
done
rmdir -v "${d}"
done
或者一行代码:
for d in */*/; do for f in "${d}"*; do [[ -f "${f}" ]] && echo mv -nv -- "${f}" "${f%/*}_${f##*/}"; done; rmdir -v "${d}"; done
echo
是为了安全的试运行,rmdir
只会删除空目录,否则会出现错误...请参见下面的演示:
ubuntu@DESKTOP:~/test$ tree Project/
Project/
├── alpha
│ ├── alpha1
│ │ ├── file1
│ │ └── file2
│ └── alpha2
│ ├── file1
│ └── file2
└── beta
├── beta1
│ ├── file1
│ └── file2
└── beta2
├── file1
└── file2
6 directories, 8 files
ubuntu@DESKTOP:~/test$ cd Project/
ubuntu@DESKTOP:~/test/Project$ for d in */*/; do for f in "${d}"*; do [[ -f "${f}" ]] && mv -nv -- "${f}" "${f%/*}_${f##*/}"; done; rmdir -v "${d}"; done
renamed 'alpha/alpha1/file1' -> 'alpha/alpha1_file1'
renamed 'alpha/alpha1/file2' -> 'alpha/alpha1_file2'
rmdir: removing directory, 'alpha/alpha1/'
renamed 'alpha/alpha2/file1' -> 'alpha/alpha2_file1'
renamed 'alpha/alpha2/file2' -> 'alpha/alpha2_file2'
rmdir: removing directory, 'alpha/alpha2/'
renamed 'beta/beta1/file1' -> 'beta/beta1_file1'
renamed 'beta/beta1/file2' -> 'beta/beta1_file2'
rmdir: removing directory, 'beta/beta1/'
renamed 'beta/beta2/file1' -> 'beta/beta2_file1'
renamed 'beta/beta2/file2' -> 'beta/beta2_file2'
rmdir: removing directory, 'beta/beta2/'
ubuntu@DESKTOP:~/test/Project$ tree
.
├── alpha
│ ├── alpha1_file1
│ ├── alpha1_file2
│ ├── alpha2_file1
│ └── alpha2_file2
└── beta
├── beta1_file1
├── beta1_file2
├── beta2_file1
└── beta2_file2
2 directories, 8 files
答案2
使用Perl 的rename
:
$ tree Project/
Project/
├── alpha
│ └── alpha1
│ ├── file1
│ └── file2
└── beta
└── beta1
├── file1
└── file2
4 directories, 4 files
rename -n 's@(Project/[^/]+)/(\w+\d+)/(file\d+)@$1/$2_$3@' ./Project/*/*/*
rmdir ./Project/*/*
当输出看起来令人满意时,删除-n
(又名)。dry-run
输出
rename(Project/alpha/alpha1/file1, Project/alpha/alpha1_file1)
rename(Project/alpha/alpha1/file2, Project/alpha/alpha1_file2)
rename(Project/beta/beta1/file1, Project/beta/beta1_file1)
rename(Project/beta/beta1/file2, Project/beta/beta1_file2)
答案3
使用贡献的zmv
模块zsh
:
% autoload -Uz zmv
% zmv -v -Q 'Project/*/*/*(.N)' '$f:h_$f:t'
mv -- Project/alpha/alpha1/file1 Project/alpha/alpha1_file1
mv -- Project/alpha/alpha1/file2 Project/alpha/alpha1_file2
mv -- Project/alpha/alpha2/file1 Project/alpha/alpha2_file1
mv -- Project/alpha/alpha2/file2 Project/alpha/alpha2_file2
mv -- Project/beta/beta1/file1 Project/beta/beta1_file1
mv -- Project/beta/beta1/file2 Project/beta/beta1_file2
mv -- Project/beta/beta2/file1 Project/beta/beta2_file1
mv -- Project/beta/beta2/file2 Project/beta/beta2_file2
该-Q
开关打开(.N)
仅匹配纯文件的裸 glob 限定符,因此它不会尝试移动任何子目录。替换模式使用历史样式H埃德和吨ail 修饰语。
现在我们只需要删除空目录:
% rmdir -v Project/*/*(/^F)
rmdir: removing directory, 'Project/alpha/alpha1'
rmdir: removing directory, 'Project/alpha/alpha2'
rmdir: removing directory, 'Project/beta/beta1'
rmdir: removing directory, 'Project/beta/beta2'
离开
% tree Project
Project
├── alpha
│ ├── alpha1_file1
│ ├── alpha1_file2
│ ├── alpha2_file1
│ └── alpha2_file2
└── beta
├── beta1_file1
├── beta1_file2
├── beta2_file1
└── beta2_file2
2 directories, 8 files