我有一个 Web 应用程序,它访问运行 Linux 的远程存储以获取一些文件,问题是远程存储当前有 300 万个文件,因此正常访问方式有点棘手。
因此,我需要编写一个脚本,使其更易于使用,该脚本将根据文件的创建日期,特别是它们的名称,将文件重新组织到多个文件夹中,我制作了该脚本并且它有效还好,本来打算做它该做的事,但是太慢了,十二个小时都完成不了(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
为了类型1文件数量:
the file==>MY_AMAZING_FILE_THAT_IMADEIN_YEAR_TY.pdf
我需要获取年份,以便执行反向剪切:
year=$(echo "$file" | rev | cut -d '_' -f 2 | rev );;
为了类型2文件数量:
the file==>MY_AMAZING_FILE_THAT_IMADE_IN_YEAR_WITH_TY.pdf
ETC...
然后我可以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
或awk
或字符串操作,但我真的不明白如何使用。
答案1
要在不使用外部实用程序的情况下获取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) '_'
更新问题后:
将 PDF 文件从下面移动topdir
到一个目录/some/path/destination/<year>/<parent>
,其中<year>
文件的文件名中包含年份,并且<parent>
是文件所在原始目录的基本名称:
find topdir -type f -name '*.pdf' -exec bash ./movefiles.sh {} +
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
答案2
您可以申请sed提取方法年价值:
year=$(sed -E 's/.*_([0-9]{4})_TY\.pdf/\1/' <<<"$file")