移动某个子目录

时间:2017-02-19 09:25:58

标签: linux

我有这样的目录结构:

/root/1232/medium
/root/1234/medium
/root/1245/medium
/root/1253/medium
/root/1263/medium ...

在这些文件夹中的每一个1232,1234,1245 ...我有我想要移动到他们的媒体子目录的文件。这意味着/ root / 1232 /中的所有文件都应该移动到/ root / 1232 / medium,并且/ root / 1234 /中的所有文件都应该移动到/ root / 1234 / medium。 我尝试了各种各样的查找版本,但没有一个能够工作。 问题是我有超过15000个文件夹,否则我会手动移动它。 感谢。

2 个答案:

答案 0 :(得分:1)

如果您使用的是最新版本的bash(即,年龄不超过10年),您可以通过发出以下命令启用扩展通配:

shopt -s extglob

在许多其他有用的功能中,扩展的globbing允许你通过调用!(pattern)

来做负面的globbing

因此,要解决您的问题,您可能会执行类似

的操作
for folder in /root/12* ; do
  mv $folder/!(medium) $folder/medium/
done

将迭代匹配模式/root/12*的所有文件夹(或任何其他项目),然后对于每个文件夹,只要未调用medium,它们就会尝试移动所有内容。到那里实际上称为medium的目录。那是关于它的:)

有关负/反向通配的详细信息,另请参阅this SO question

如果出于某种原因你不想启用扩展通配(或者你的bash不支持它),你可以做一些反向grepping:

for basefolder in /root/12* ; do
  for entry in $(ls $basefolder | grep -v medium) ; do
    mv $basefolder/$entry $basefolder/medium
  done
done

答案 1 :(得分:0)

命令:

find /root/* -mindepth 1 -maxdepth 1 -type f

-type f的子目录中查找深度为1(-mindepth 1 -maxdepth 1)的所有文件(/root)。 -mindepth参数强制find跳过/root(它们深度为0)的文件,否则将会找到这些文件。

运行上面的命令并验证它是否生成了您要移动的文件列表,而不是其他任何内容。您可以使其更严格,以确保它不返回您不想移动的文件。例如,如果您知道要处理的/root的所有子目录都以12开头,那么您可以使用find /root/12* ...

如果您确定拥有生成正确文件列表的命令,请将其嵌入for命令,如下所示:

IFS=$'\n'
for i in $(find /root/* -mindepth 1 -maxdepth 1 -type f); do
    mv "$i" "${i%/*}/medium/"
done

只是为了确保它不会破坏任何内容,将echo放在mv前面并运行它以查看它将执行的操作。如果一切正常,请删除echo并享受。

备注

确保使用bash运行上述命令。 $()构造是特定于bash的;其他炮弹可能会或可能不会理解它,或者它们可能以不同的方式解释它。表达相同行为的更便携方式是使用反引号(``)而不是$()

如何运作

命令替换运算符($()``)运行它包含的命令并捕获其输出。 find命令的输出是要移动的文件列表。

$()生成的字符串然后由for迭代;在每次迭代中,环境变量i设置为find输出的一行。 find输出的每一行都包含我们要移动的一个文件的路径。

IFS块之前将$'\n'环境变量设置为for可确保find的输出仅在换行符上拆分。 IFS的默认值(“内部字段分隔符”)为<space><tab><newline>如果找到具有空格的文件,则for命令会错误地将find的输出拆分为IFS=$'\n'在他们的名字。

如果您完全确定要移动的文件名称中没有空格,则可以删除mv行。

接下来,在每次迭代中,构建并执行${i%/*}命令行。 i参数展开会从%的值中删除与/*模式匹配的最短右边(${i%/*}/medium/)。删除的部分是文件名和完整文件路径中的斜杠。

medium/基本上用mv "$i" "$(dirname $i)/medium/" 替换文件名。另一种可能的方法是:

dirname

它使用命令$i仅从${i%/*}中提取目录(删除文件名)。

第一种方式(git log -- myFile )是首选,因为它更快。