我正在开发一个排序/过滤 cron 脚本,用于根据一组常量字符串(日志文件、历史记录、数据集等)处理传入文件。要排序的文件都位于一个公共文件夹下,一些位于主文件夹中,一些位于子文件夹中。我正在 Debian/bash (MX Linux) 上进行此工作,目前这是我主要关心的问题,但它最终将转移到 Debian/ash (dCore Linux) 系统。
- 文件和文件夹名称总是包含 STRING,且 STRING 可以包含大小写混合。
- 文件名及其所在的子文件夹可以两个都包含 STRING。
- 文件夹和STRING 可以包含文件没有细绳。它们应该与其父文件夹一起移动。
- 文件和文件夹名称可以包含空格、圆括号、方括号。
例子:
/main/ # folder being searched
/main/filename.log # should not be moved
/main/filename containing-STRING.log # should be moved
/main/subfolder/ # should not be moved
/main/subfolder/file.txt # should not be moved
/main/subfolder.with STRING in-name/ # should be moved
/main/subfolder.with STRING in-name/STRING-file.log # should be moved along with parent
/main/subfolder.with STRING in-name/file.txt # should be moved along with parent
我的出发点:
find . -iname '*STRING*' -exec mv {} ../offload/ \;
即使它给出“文件未找到”错误,这也是有效的,可能是因为在移动其父文件夹时文件已经被移动。由于任何子文件夹始终包含 STRING,因此我不一定需要或想要“查找”它们的内容。我只需要移动父文件夹。所以我尝试使用“-maxdepth 0”仅在主文件夹中“查找”STRING。
find . -maxdepth 0 -iname '*STRING*' -exec mv {} ../offload/ \;
添加 -maxdepth 开关不起作用。没有“找不到文件”警告,但也没有任何内容被移动。对我哪里出错有什么建议吗?
编辑:我只能访问 bash shell,并最终访问 dCore 系统及其默认的 ash shell。这是一个仅限 cli 的迷你系统;没有空间添加另一个 shell 环境。
我努力了:
find . -maxdepth 0 -type d -iname '*STRING*' -exec mv {} ../offload/ \;
当我运行它时,它会返回到提示符,没有错误,但没有任何内容被移动。
@cas是的,我确实需要保留目录结构,但是您的两个示例都不应该满足搜索。我只想查找并移动主文件夹中与 STRING 匹配的文件和目录。因此:
/main/filename-with-STRING # match
/main/folder-with-STRING/ # match
/main/folder-with-STRING/foo/ # moved along with parent
/main/subfolder/filename-with-STRING # no match
/main/subfolder/folder-with-STRING/ # no match
答案1
听起来您首先要移动所有匹配的目录,然后移动所有保留并匹配的文件、符号链接……。
您可以通过-type d
在第一次find
运行时指定目录和'(' -not -type d ')'
第二次find
运行时指定目录来实现此目的。
但是,您可以find
使用现代 shell 来完成此操作:
#!/usr/bin/zsh
# probably already enabled! So, just for reference:
setopt extended_glob
# also match "hidden" files, i.e., such that start with a dot
setopt dotglob
# we don't care about case!
setopt nocaseglob
# move all directories.
mv **/*STRING*(/) ../offload/
# move all non-directories
mv **/*STRING*(^/) ../offload/