在使用文件时列出文件-Shell Linux

在使用文件时列出文件-Shell Linux,linux,bash,shell,sh,Linux,Bash,Shell,Sh,我有一个数据库服务器,它的基本工作是导入一些特定的文件,进行一些计算,并在web界面中提供数据 它计划在下周更换硬件,它需要迁移数据库。但其中有一个问题:实际数据库已损坏,并且在web界面中显示了一些错误。这是由于导入/计算时服务器冻结,这就是更换的原因 因此,我不愿意只转储数据库并在新服务器中恢复。仍然使用损坏的数据库是没有意义的,而转储旧服务器的速度非常慢。我有一个从所有要导入的文件备份(当前的数字是551),我正在编写一个脚本来“重新导入”所有文件,并再次拥有一个好的数据库 实际服务器导入

我有一个数据库服务器,它的基本工作是导入一些特定的文件,进行一些计算,并在web界面中提供数据

它计划在下周更换硬件,它需要迁移数据库。但其中有一个问题:实际数据库已损坏,并且在web界面中显示了一些错误。这是由于导入/计算时服务器冻结,这就是更换的原因

因此,我不愿意只转储数据库并在新服务器中恢复。仍然使用损坏的数据库是没有意义的,而转储旧服务器的速度非常慢。我有一个从所有要导入的文件备份(当前的数字是551),我正在编写一个脚本来“重新导入”所有文件,并再次拥有一个好的数据库

实际服务器导入每个新文件大约需要20分钟。假设新服务器由于其强大的功能,每个文件需要10个。。。好久不见了!问题来了:它每小时接收一个新文件,所以当它完成任务时会有更多的文件

还原脚本的启动方式如下:

for a in $(ls $BACKUP_DIR | grep part_of_filename); do
问题是:这个“ls”在出现时会有新的文件名吗?文件名基于时间戳,因此它们将位于列表的末尾

或者这个“ls”只执行一次,结果就转到一个临时变量


谢谢。

ls
将在开始时执行一次,并且不会显示任何新文件

您可以重写该语句,在每个循环开始时再次列出文件(如Trey所述,最好使用
find
,而不是
ls
):

但这有一个大问题:它会一次又一次地重复处理相同的文件

脚本需要记录完成了哪些文件。然后,它可以再次列出目录并处理任何(且仅限于)新文件。这里有一个方法:

touch ~/done.list
cd $BACKUP_DIR
# loop while f=first file not in done list:
#   find                       list the files; more portable and safer than ls in pipes and scripts
#   fgrep -v -f ~/done.list    pass through only files not in the done list
#   head -n1                   pass through only the first one
#   grep .                     control the loop (true iff there is something)
while f=`find * -type f | fgrep -v -f ~/done.list | head -n1 | grep .`; do
  <process file $f>
  echo "$f" >> ~/done.list
done
touch~/done.list
cd$BACKUP\u DIR
#f=第一个文件未在完成列表中时循环:
#查找并列出文件;在管道和脚本中比ls更具可移植性和安全性
#fgrep-v-f~/done.list仅传递不在完成列表中的文件
#头部-n1仅通过第一个
#格雷普。控制循环(如果有东西,则为真)
而f=`find*-typef | fgrep-v-f~/done.list | head-n1 | grep.`;做
回显“$f”>>~/done.list
完成

解析
ls
的输出通常是个坏主意。如果可能,请改用全局搜索。文件名本身并不是问题。将新文件添加到列表中。@AlexBueno如果任何文件名包含空格或被扩展为文件模式,这将是一个非常大的问题。@chepner不是这样。您假设不是这样。最好编写能够处理意外情况的代码。谢谢!我要试试这个!这是迭代
find
输出的错误方法。看见此外,
find
的输出是不可解析的,原因与
ls
的输出是苛刻的相同。想用更好的答案来支持这些主张吗?;)@到目前为止,韦伯工作得很好!我还没有新的硬件,但旧的数据库决定堵塞!所以无论如何,我是在另一个硬件上进行恢复的。@chepner,虽然我尊重你的知识和勤奋,但我认为有时quick-n-dirty是一种方法,例如,对于一个时间敏感的任务,只需在一个系统上工作一次。通常,我会像在bash常见问题解答中那样
find | while read
,但在这种情况下,需要额外的while外部循环来获取新文件。我认为这个答案可以处理空格和有趣的字符,但对于数千个文件来说都会失败。如果有很多文件,最好在查找时执行以下操作:
-f型| grep-q-m1。;一定要找到-读取f时键入f | fgrep-v-f~/done.list |;执行…
touch ~/done.list
cd $BACKUP_DIR
# loop while f=first file not in done list:
#   find                       list the files; more portable and safer than ls in pipes and scripts
#   fgrep -v -f ~/done.list    pass through only files not in the done list
#   head -n1                   pass through only the first one
#   grep .                     control the loop (true iff there is something)
while f=`find * -type f | fgrep -v -f ~/done.list | head -n1 | grep .`; do
  <process file $f>
  echo "$f" >> ~/done.list
done