1

我继承控制权的旧版 Web 应用程序似乎已达到我的 Web 服务器上文件夹中的最大子目录数。每当在系统中创建文章时,它的静态内容都会放置在与 pattern 匹配的文档根目录的子目录中/uploads/story/{STORY_ID}/。但是现在系统无法在文件夹中创建任何新目录/uploads/story/

我想分两步解决这个问题,但我不确定如何运行必要的 linux 命令来实现这一点。你能帮忙吗?

  1. 作为为我争取更多时间来实现更好的目录结构的临时解决方案,我想归档 STORY_ID 小于 1000 的所有故事的静态内容。这些应该/uploads/story//uploads/story_archive/.

  2. 我会将上传路径更改为/uploads/story/{THOUSANDS}/{STORY_ID}/在代码中,但需要能够将其中的所有文件夹移动/uploads/story/为这种格式。例如/uploads/story/65312/会变成/uploads/story/65/65312/. 我怎样才能做到这一点?

编辑

修复 (1) 就像运行一样简单:

$ cd /path/to/uploads/
$ mkdir story_archive
$ for i in {1..999}; do mv story/$i story_archive/; done
4

2 回答 2

1

鉴于您确定/uploads/story/*会在零件中给您一个编号*,您可以执行以下操作(注意:备份整个内容以防万一):

# update this based on your actual directory
path_to_fix=/uploads/stories

# move the directories out of the way so they don't get mixed up
mv $path_to_fix $path_to_fix/../temp
mkdir $path_to_fix > /dev/null 2>&1

# get all directories to be moved
dirs=$(ls $path_to_fix/../temp)

# for each of them
for d in $dirs; do
  # get the basename, which is store_id
  id=$(basename $d)
  # divide by 1000
  sub=$((id / 1000))
  # create the appropriate directory
  mkdir $path_to_fix/$sub > /dev/null 2>&1
  # move the original directory to that sub-directory
  mv $path_to_fix/../temp/$d $path_to_fix/$sub
done

# cleanup
rm -Rf $path_to_fix/../temp
于 2013-01-16T09:59:01.763 回答
1

对于临时修复,您可以使用 for 循环和 glob

for path in /uploads/story/*; do
   storyid=${path##*/}
   if [[ ${storyid} -lt 1000 ]]; then
        mv "${path}" /uploads/story_archive/${storyid}
   fi
done

这将使用 $path var 中的完整路径遍历 /uploads/story/ 目录中的所有目录。bash 构造 ${variable##pattern} 将从变量的左侧删除最长的子字符串匹配模式,在这种情况下,所有前导目录只留下 storyid 存储在 var 中。然后我们检查楼层 ID 是否小于 1000 并将其移动到故事存档中。

下一点。

for path in /uploads/story/*; do
   storyid=${path##*/}
   if [[ $storyid -ge 1000 ]]; then
       thous=${storyid%%???}
       [[ -d/uploads/story/$thous/ ]] || mkdir /uploads/story/$thous/
       mv $path /uploads/story/$thous/
   fi
done

好的,我们再次遍历所有目录并提取故事 ID。这次虽然我们确保 storyid 大于或等于 1000 并使用 %%??? 从 storyid 中删除最后三个字符(与 ## 技巧相同,但从变量的右侧删除。)然后我们查看 thousads 目录是否存在,如果不存在则创建并移动该目录。

您甚至可以一次扫描并同时完成两项任务

for path in /uploads/story/*; do
   storyid=${path##*/}
   if [[ $storyid -lt 1000 ]]; then
       mv "${path}" /uploads/story_archive/${storyid}
   else
       thous=${storyid%%???}
       [[ -d/uploads/story/$thous/ ]] || mkdir /uploads/story/$thous/
       mv $path /uploads/story/$thous/
   fi
done
于 2013-01-16T10:05:40.160 回答