我有一个目录,里面有大量带有不同扩展名的文件。我想要做的是将每个扩展名移动到一个以扩展名本身命名的文件夹中,而那些没有扩展名的文件则移动到名为的文件夹中unkown
。
例如我有文件a.txt
,,,,,,....b.txt
a.pdf
b.pdf
a.mp4
file
newfile
结果将有 4 个目录,分别名为txt
, pdf
, mp4
,unkonw
该txt
目录包含文件a.txt
,b.txt
该pdf
目录包含文件a.pdf
,b.pdf
该mp4
目录包含文件a.mp4
该unkonw
目录包含文件file
,newfile
答案1
这是另一种方法:
mkdir -p unknown;
for f in *; do
[[ $f =~ \. ]] && mkdir -p "${f##*.}" &&
mv "$f" "${f##*.}"/ ||
mv "$f" unknown/; done
解释
&&
意思是“只有左边的命令成功执行时才运行右边的命令”。||
表示“仅当左侧命令失败时才运行右侧命令”。两个符号组合起来可以起到块的作用if/else
。mkdir -p unknown;
:创建unknown
目录。这样-p
,mkdir
如果目录存在,就不会发出抱怨。for f in *
:针对当前目录中的所有文件和目录。[[ $f =~ \. ]] &&
:如果当前文件/目录名称包含.
,如果它有扩展名,那么......mkdir -p "${f##*.}"/
:该构造将从变量的开头${var##pat}
删除最长的匹配项。此处,可以是任何直到点的字符,因此这将仅留下扩展名。因此,如果扩展名的目录不存在,则此命令将创建该目录。pat
$var
pat
mv "$f" "${f##*.}"/
:mv
然后将文件移动到相关目录中。|| mv "$f" unknown/;
:如果前一个命令失败(如果此文件/目录)没有扩展名,则将其移动到unknown
。
请注意,这将打印此错误消息,但您可以放心地忽略它:
mv: cannot move ‘unknown’ to a subdirectory of itself, ‘unknown/unknown’
如果您只需要移动文件而不移动目录(上述命令也会移动名为dir.foo
into 的目录foo/
),请使用以下命令:
mkdir -p unknown;
for f in *; do
[[ -f $f ]] &&
if [[ $f =~ \. ]]; then
mkdir -p "${f##*.}" &&
mv "$f" "${f##*.}"/;
else mv "$f" unknown/; fi;
done
答案2
此bash
脚本将执行以下操作:使用bash script.sh <path>
或运行它./script.sh <path>
,其中<path>
是包含文件的文件夹的路径:
#!/bin/bash
for path in ${1}/*
do
if [ -f "${path}" ]
then
extension="$(<<< "${file}" sed -rn 's/^.*\.(.*)$/\1/p')"
if [ -n "${extension}" ]
then
mkdir -p "${1}/${extension}"
mv "${path}" "${1}/${extension}"
else
mkdir -p "${1}/unknown"
mv "${path}" "${1}/unknown"
fi
fi
done
tree
在目录上运行脚本之前和之后的输出tmp
:
ubuntu@ubuntu:~$ tree tmp
tmp
├── a.mp4
├── a.pdf
├── a.txt
├── b.pdf
├── b.txt
├── file
├── folder
└── newfile
1 directory, 7 files
ubuntu@ubuntu:~$ bash script tmp/
ubuntu@ubuntu:~$ tree tmp
tmp
├── folder
├── mp4
│ └── a.mp4
├── pdf
│ ├── a.pdf
│ └── b.pdf
├── txt
│ ├── a.txt
│ └── b.txt
└── unknown
├── file
└── newfile
5 directories, 7 files