Par*_*rto 15 command-line files
我正在寻找一种方法(最好是终端)通过它们的第一个字母来组织 1000 多种字体。
基本上创建目录,A-Z, #然后根据文件名的第一个字符将字体文件移动到这些目录。以数字 [0-9] 或其他特殊字符开头的字体要移动到#目录中。
Jac*_*ijm 13
一个晚期的python选项:
#!/usr/bin/env python3
import os
import sys
import shutil
def path(dr, f): return os.path.join(dr, f)
dr = sys.argv[1]
for f in os.listdir(dr):
fsrc = path(dr, f)
if os.path.isfile(fsrc):
s = f[0]; target = path(dr, s.upper()) if s.isalpha() else path(dr, "#")
if not os.path.exists(target):
os.mkdir(target)
shutil.move(fsrc, path(target, f))
Run Code Online (Sandbox Code Playgroud)
move_files.py以目录为参数运行它:
python3 /path/to/move_files.py /path/to/files
Run Code Online (Sandbox Code Playgroud)如果确实需要,脚本只会创建(子)目录(-ies)(大写)
剧本:
列出文件,获取第一个字符(定义源路径):
python3 /path/to/move_files.py /path/to/files
Run Code Online (Sandbox Code Playgroud)检查项目是否是文件:
for f in os.listdir(dr):
s = f[0]; fsrc = path(dr, f)
Run Code Online (Sandbox Code Playgroud)为第一个字符是否为 alpha 定义目标文件夹:
if os.path.isfile(fsrc):
Run Code Online (Sandbox Code Playgroud)检查文件夹是否已经存在,如果不存在则创建它:
target = path(dr, s.upper()) if s.isalpha() else path(dr, "#")
Run Code Online (Sandbox Code Playgroud)将项目移动到其相应的文件夹中:
if not os.path.exists(target):
os.mkdir(target)
Run Code Online (Sandbox Code Playgroud)Dav*_*ter 11
只需两个命令和两个正则表达式即可轻松阅读代码:
mkdir -p '#' {a..z}
prename -n 's|^[[:alpha:]]|\l$&/$&|; s|^[0-9]|#/$&|' [[:alnum:]]?*
Run Code Online (Sandbox Code Playgroud)
如果您有大量文件要移动,太多而无法放入进程参数列表(是的,有一个限制,可能只有几千字节),您可以使用不同的命令和管道生成文件列表以prename,例如:
find -mindepth 1 -maxdepth 1 -name '[[:alnum:]]?*' -printf '%f\n' |
prename -n 's|^[[:alpha:]]|\l$&/$&|; s|^[0-9]|#/$&|'
Run Code Online (Sandbox Code Playgroud)
[[:alnum:]]?*如果没有文件与 glob 模式匹配,这有一个额外的好处,即不尝试移动文字文件名。find还允许比 shell globbing 多得多的匹配条件。另一种方法是设置nullglobshell 选项并关闭prename. 1
在这两种情况下,删除-n开关以实际移动文件,而不仅仅是显示它们将如何移动。
附录:您可以再次删除空目录:
rmdir --ignore-fail-on-non-empty '#' {a..z}
Run Code Online (Sandbox Code Playgroud)
1 shopt -s nullglob; prename ... <&-
我没有想出一个很好的方法来使目录名称大写(或用大写字母移动文件),尽管之后您可以使用rename...
mkdir {a..z} \#; for i in {a..z}; do for f in "$i"*; do if [[ -f "$f" ]]; then echo mv -v -- "$f" "$i"; fi; done; done; for g in [![:alpha:]]*; do if [[ -f "$g" ]]; then echo mv -v -- "$g" \#; fi; done
Run Code Online (Sandbox Code Playgroud)
或更易读:
mkdir {a..z} \#;
for i in {a..z}; do
for f in "$i"*; do
if [[ -f "$f" ]]; then
echo mv -v -- "$f" "$i";
fi
done
done
for g in [![:alpha:]]*; do
if [[ -f "$g" ]]; then
echo mv -v -- "$g" \#
fi
done
Run Code Online (Sandbox Code Playgroud)
echo测试后删除以实际移动文件
进而
rename -n 'y/[a-z]/[A-Z]/' *
Run Code Online (Sandbox Code Playgroud)
-n如果测试后看起来不错,请删除并再次运行。
如果你不介意 zsh,一个函数和几个zmv命令:
mmv() {echo mkdir -p "${2%/*}/"; echo mv -- "$1" "$2";}
autoload -U zmv
zmv -P mmv '([a-zA-Z])(*.ttf)' '${(UC)1}/$1$2'
zmv -P mmv '([!a-zA-Z])(*.ttf)' '#/$1$2'
Run Code Online (Sandbox Code Playgroud)
该mmv函数创建目录并移动文件。zmv然后提供模式匹配和替换。首先,移动以字母开头的文件名,然后是其他所有内容:
$ zmv -P mmv '([a-zA-Z])(*.ttf)' '${(UC)1}/$1$2'
mkdir -p A/
mv -- abcd.ttf A/abcd.ttf
mkdir -p A/
mv -- ABCD.ttf A/ABCD.ttf
$ zmv -P mmv '([!a-zA-Z])(*.ttf)' '#/$1$2'
mkdir -p #/
mv -- 123.ttf #/123.ttf
mkdir -p #/
mv -- ?.ttf #/?.ttf
Run Code Online (Sandbox Code Playgroud)
在没有echoinmmv定义的情况下再次运行以实际执行移动。
包含字体的目录中的以下命令应该可以工作,如果要从字体存储目录之外使用,请更改for f in ./*为for f in /directory/containing/fonts/*. 这是一种非常基于 shell 的方法,所以速度很慢,而且也是非递归的。如果存在以匹配字符开头的文件,这只会创建目录。
target=/directory/to/store/alphabet/dirs
mkdir "$target"
for f in ./* ; do
if [[ -f "$f" ]]; then
i=${f##*/}
i=${i:0:1}
dir=${i^}
if [[ $dir != [A-Z] ]]; then
mkdir -p "${target}/#" && mv "$f" "${target}/#"
else
mkdir -p "${target}/$dir" && mv "$f" "${target}/$dir"
fi
fi
done
Run Code Online (Sandbox Code Playgroud)
作为一个衬垫,再次从字体存储目录中:
target=/directory/to/store/alphabet/dirs; mkdir "$target" && for f in ./* ; do if [[ -f "$f" ]]; then i=${f##*/}; i=${i:0:1} ; dir=${i^} ; if [[ $dir != [A-Z] ]]; then mkdir -p "${target}/#" && mv "$f" "${target}/#"; else mkdir -p "${target}/$dir" && mv "$f" "${target}/$dir" ; fi ; fi ; done
Run Code Online (Sandbox Code Playgroud)
使用 find 的方法,具有类似的字符串操作,使用 bash 参数扩展,这将是递归的,并且应该比纯 shell 版本快一些:
find . -type f -exec bash -c 'target=/directory/to/store/alphabet/dirs ; mkdir -p "$target"; f="{}" ; i="${f##*/}"; i="${i:0:1}"; i=${i^}; if [[ $i = [[:alpha:]] ]]; then mkdir -p "${target}/$i" && mv "$f" "${target}/$i"; else mkdir -p "${target}/#" && mv "$f" "${target}/#"; fi' \;
Run Code Online (Sandbox Code Playgroud)
或更易读:
find . -type f -exec bash -c 'target=/directory/to/store/alphabet/dirs
mkdir -p "$target"
f="{}"
i="${f##*/}"
i="${i:0:1}"
i=${i^}
if [[ $i = [[:alpha:]] ]]; then
mkdir -p "${target}/$i" && mv "$f" "${target}/$i"
else
mkdir -p "${target}/#" && mv "$f" "${target}/#"
fi' \;
Run Code Online (Sandbox Code Playgroud)
小智 5
使用tr, thenmkdir和 将每个文件名映射到目录名mv:
find /src/dir -type f -print0 |
xargs -0 -I{} bash -c \
'dir=/dest/$(basename "{}" | cut -c1 | tr -C "a-zA-Z\n" "#" | tr "a-z "A-Z"); mkdir -p $dir; mv "{}" $dir'
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4034 次 |
| 最近记录: |