我有一个 web 应用程序,它访问运行 Linux 的远程存储以获取一些文件,问题是远程存储当前有 300 万个文件,因此访问正常方式有点棘手。
所以我需要编写一个脚本,让它更容易使用,这个脚本将根据文件的创建日期和特别是它们的名称将文件重新组织到多个文件夹中,我制作了脚本并且它起作用了挺好的,本来打算做它想做的,但是太慢了,12个小时才能完全完成(12:13:48 to be precise)
。
我认为这是缓慢的从多来cut
,并rev
呼吁我做。
例子:
我ls
使用 for 循环的命令获取文件名,对于每个文件,我获取父目录,并且根据父目录,我可以获得正确的年份:
case "$parent" in
( "Type1" )
year=$(echo "$fichier" | rev | cut -d '_' -f 2 | rev );;
( "Type2" )
year=$(echo "$fichier" | rev | cut -d '_' -f 2 | rev);;
( "Type3" )
year=$(echo "$fichier" | rev | cut -d '_' -f 1 | rev | cut -c 1-4);;
( "Type4" )
year=$(echo "$fichier" | rev | cut -d '_' -f 1 | rev | cut -c 1-4);;
( "Type5" )
year=$(echo "$fichier" | rev | cut -d '_' -f 1 | rev | cut -c 1-4);;
esac
Run Code Online (Sandbox Code Playgroud)
对于类型1的文件:
the file==>MY_AMAZING_FILE_THAT_IMADEIN_YEAR_TY.pdf
Run Code Online (Sandbox Code Playgroud)
我需要得到年份,所以我进行了反向切割:
year=$(echo "$file" | rev | cut -d '_' -f 2 | rev );;
对于类型 2的文件:
the file==>MY_AMAZING_FILE_THAT_IMADE_IN_YEAR_WITH_TY.pdf
Run Code Online (Sandbox Code Playgroud)
等等...
然后我可以mv
自由的文件:mv $file /some/path/destination/$year/$parent
然而这是最简单的例子,有些文件要复杂得多,所以要获得 1 个信息,我需要执行 4 次操作,1 echo , 2rev and 1echo
.
当脚本运行时50 files/sec to 100 files\s
,我的速度达到了,我通过执行一个wc-l output.txt
脚本获得了这个信息。
有什么我可以做的让它更快吗?或另一种剪切文件名的方法?我知道我可以使用sed
orawk
或 string 操作,但我并不真正理解如何。
要在不使用外部实用程序的情况下获取YEAR
文件名部分MY_AMAZING_FILE_THAT_IMADEIN_YEAR_TY.pdf
:
name='MY_AMAZING_FILE_THAT_IMADEIN_YEAR_TY.pdf'
year=${name%_*} # remove everything after the last '_'
year=${year##*_} # remove everything up to the last (remaining) '_'
Run Code Online (Sandbox Code Playgroud)
更新问题后:
将 PDF 文件从 under 移动topdir
到一个目录/some/path/destination/<year>/<parent>
,其中<year>
在文件的文件名中找到年份,并且<parent>
是在其中找到文件的原始目录的基本名称:
find topdir -type f -name '*.pdf' -exec bash ./movefiles.sh {} +
Run Code Online (Sandbox Code Playgroud)
movefiles.sh
是当前目录下的shell脚本:
#!/bin/bash
destdir='/some/path/destination'
for name; do
# get basename of directory
parent=${name%/*}
parent=${parent##*/}
# get the year from the filename:
# - Pattern: _YYYY_ (in the middle somewhere)
# - Pattern: _YYYYMMDD.pdf (at end)
if [[ "$name" =~ _([0-9]{4})_ ]] ||
[[ "$name" =~ _([0-9]{4})[0-9]{4}\.pdf$ ]]; then
year="${BASH_REMATCH[1]}"
else
printf 'No year in filename "%s"\n' "$name" >&2
continue
fi
# make destination directory if needed
# (remove echo when you have tested this at least once)
if [ ! -d "$destdir/$year/$parent" ]; then
echo mkdir -p "$destdir/$year/$parent"
fi
# move file
# (remove echo when you have tested this at least once)
echo mv "$name" "$destdir/$year/$parent"
done
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
743 次 |
最近记录: |