按顺序加载文件

按顺序加载文件

我需要在 shell 脚本中加载具有相同文件名的多个文件,但在每个文件名前面附加的是 YYMMDDPERSONNEL 示例:231102PERSONNEL 和 230103PERSONNEL 同一目录中还有许多其他文件,因此文件名在排序中很重要。我需要对要加载的文件从最旧到最新进行排序。

目前我所拥有的只是设计用于一次处理一个文件。

答案1

这是一个简单的任务,有管道。

find . -maxdepth 1 -type f -name '*PERSONNEL.gz' -print | \
    sed -e 's%^./%%' | \
    sort | \
    xargs -r /bin/echo 

阅读man页面。

这是一个快速概述:

  • find打印文件名列表STDOUT
  • sed使它看起来更好(更改./231102PERSONNEL.gz231102PERSONNEL.gz
  • sort对列表进行排序。
  • xargs放置尽可能多的文件(请xargs --show-limits </dev/null参阅你的限制)并对列表的其余部分重复“命令”
  • /bin/echo是一个占位符。

答案2

默认情况下,Shell 全局按词汇顺序展开,并且您的情况下的词汇顺序与时间顺序 (顺序的)文件的顺序,只要它们都来自同一世纪(例如,从 1900 年到 1999 年,忽略 20世纪实际上是从 1901 年到 2000 年)。

zsh

set -o extendedglob
for f ( [0-9](#c6)PERSONNEL.sql.gz(N) ) gunzip < $f | your-sql-loader

(或者,[0-9](#c6)PERSONNEL.sql.gz(NOn)如果您需要O按 ame 顺序排列文件n,则按照您最初的要求相反(大写o))。

假设your-sql-loader可以从标准输入获取输入。如果需要将其作为文件名参数传递:

for f ( [0-9](#c6)PERSONNEL.sql.gz(N) ) your-sql-loader <(gunzip < $f)

或者,如果该文件名参数必须是常规文件:

for f ( [0-9](#c6)PERSONNEL.sql.gz(N) ) your-sql-loader =(gunzip < $f)

您很可能能够做到:

gunzip -dc -- [0-9](#c6)PERSONNEL.sql.gz | your-sql-loader

也就是说,将所有反向排序的文件的所有未压缩内容串联起来your-sql-loader

更一般地说,很少需要在磁盘上存储文件的未压缩版本。最好即时解压缩它并同时将其提供给使用它的任何应用程序。

如果消费者应用程序不按顺序读取数据(如果这意味着是的话,那么这里会令人惊讶,那么您只需要在磁盘上解压缩它(就像=(...)上面的方法完成的那样,在临时文件中获取输出)) gunzipSQL)。

如果您确实必须使用 (t)csh 正如标签所暗示的那样,这在本世纪将是非常令人惊讶的,假设文件名不包含换行符的等效内容将是:

gunzip -dc -- "`ls -rd -- [0-9][0-9][01][0-9][0-3][0-9]PERSONNEL.sql.gz`" | your-sql-loader

其中ls -r按名称对文件进行反向排序;其"`...`"输出被检索并分成非空行成分。

由于csh没有 zsh[0-9](#c6)或 ksh的等效项{6}([0123456789])来匹配 6 位数字,因此我们专门匹配每个数字,并借此机会更严格地匹配月份和日期数字。

oe[code]如果您有上个世纪的文件,则可以使用 the或o+functionglob 限定符在 zsh 中定义自定义排序顺序。

[0-9](#c6)PERSONNEL.sql.gz(Noe['REPLY[1,0]=$(( 19 + ($REPLY[1,2] < 70) )'])

也就是说,指示 zsh 根据我们在其前面添加 20 或 19 的文件名对 glob 进行排序,具体取决于前 2 位数字是否构成大于或小于 70 的数字(您需要调整基于您的实际数据集的截止年份;此处选择 1970 年,因为这是 Unix 纪元时间的开始)。

相关内容