我在一个目录中有数千个文件,我想根据它们的文件名将它们分类到子目录中。它们都以p- [number] _n- [number] _a- [number]。[ext]的集合结构一致地命名。
这是一个小样本...
我需要的是这样的文件夹结构:
p-12345
⊢ n-987
⊢ p-12345_n-987_a-1254.jpg
⊢ p-12345_n-987_a-9856.pdf
⊢ p-12345_n-987_a-926.docx
⊢ n-384
⊢ p-12345_n-384_a-583.pdf
⊢ p-12345_n-384_a-987.pdf
p-2089
⊢ n-2983
⊢ p-2089_n-2983_a-2348.gif
⊢ n-1982
⊢ p-2089_n-1982_a-403.jpeg
p-38422
⊢ n-2311
⊢ p-38422_n-2311_a-126.pdf
⊢ p-38422_n-2311_a-5231.docx
我希望这是有道理的。
是否可以编写脚本来以这种方式组织文件?
编辑:澄清:是的,我的问题应该是如何编写脚本来组织文件?:)我对Unix和一般命令行来说是新手。到目前为止,我仅编写/使用了基本的Shell脚本。我有一个预感,答案可能会涉及正则表达式,但是除此之外,我不确定从哪里开始。
我想出的最好的主意是
我敢肯定,这比需要做的要长得多。我还希望有一些可重复的内容,以防将来需要为更多文件做这些事情。
如前所述,简短的答案是“是”。
长答案是:您可以使用bash脚本来完成此任务,该脚本awk
用于提取要作为目录结构基础的文件名元素。看起来可能像这样(在这里,更多的重点放在可读性上而不是“单行”紧凑性)。
#!/bin/bash
for FILE in p-*
do
if [[ ! -f $FILE ]]; then continue; fi
LVL1="$(awk '{match($1,"^p-([[:digit:]]+)_[[:print:]]*",fields); print fields[1]}' <<< $FILE)"
LVL2="$(awk '{match($1,"^p-([[:digit:]]+)_n-([[:digit:]]+)_[[:print:]]*",fields); print fields[2]}' <<< $FILE)"
echo "move $FILE to p-$LVL1/n-$LVL2"
if [[ ! -d "p-$LVL1" ]]
then
mkdir "p-$LVL1"
fi
if [[ ! -d "p-$LVL1/n-$LVL2" ]]
then
mkdir "p-$LVL1/n-$LVL2"
fi
mv $FILE "p-$LVL1/n-$LVL2"
done
解释:
ls
,因此FILES=$(ls p-*); for FILE in $FILES; do ...
将类似的内容视为不行)。p-
和之间的数字_n
以生成目录结构的第一级,第二级和第二级awk
之间的数字相同。想法是使用该函数,该函数不仅查找输入中指定正则表达式出现的位置,而且还为您提供数组“字段”中用圆括号括起来的所有元素的“完成”值。n-
_a
match
( ... )
有关更多信息,请参阅《高级bash脚本指南》和《GNU Awk用户指南》。
一旦您对脚本和正则表达式更加坚定,就可以使它变得更加紧凑。例如,在上面的脚本中,目录/子目录路径的生成可以很容易地压缩为一个awk
调用。
首先,由于目录名称实际上是 p-<number>
和n-<number>
,与文件名中的相同,我们也可以awk
通过编写以下内容来为我们提取这些字符:match($1,"(^p-[[:digit:]]+)_(n-[[:digit:]]+)_[[:print:]]*",fields)
awk
通过使用合适的参数同时生成目录-子目录路径,我们可以进一步减轻工作负担print
:
awk '{match($1,"(^p-[[:digit:]]+)_(n-[[:digit:]]+)_[[:print:]]*",fields); print fields[1] "/" fields[2]}'
将很容易产生(例如)p-12345/n-384
file p-12345_n-384_a-583.pdf
。如果我们将其与mkdir -p
@wurtel所指示的用法结合使用,脚本可能看起来像
for FILE in p-*
do
if [[ ! -f $FILE ]]; then continue; fi
TARGET="$(awk '{match($1,"(^p-[[:digit:]]+)_(n-[[:digit:]]+)_[[:print:]]*",fields); print fields[1] "/" fields[2]}' <<< $FILE)"
echo "move $FILE to $TARGET"
mkdir -p "$TARGET"
mv $FILE $TARGET
done
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句