我已经发出下一个命令来将一些目录移动到“build_tools”文件夹,但结果不是我预期的。
ls -l | grep 2014-03 | awk '{if ($8!=build_tools) print $8}' | xargs mkdir build_tools/{} && mv {}/ build_tools/{}/
它将文件夹“build_tools”与其余目录一起移动到 awk (zlib) 产生的文件夹之一,然后它卡在了此消息中:
mkdir: no se puede crear el directorio «zlib»: El archivo ya existe
有人能解释一下我的错误是什么吗?
编辑1:
ls -l 的输出显示:
drwxr-xr-x 3 poissonbreaker poissonbreaker 4096 2011-05-02 09:58 antlr3.2
-rw-r--r-- 1 poissonbreaker poissonbreaker 318588 2011-05-17 16:21 AppFramework-1.03.jar
-rw-r--r-- 1 poissonbreaker poissonbreaker 0 2014-03-04 09:53 awk
drwxr-xr-x 4 poissonbreaker poissonbreaker 4096 2013-01-11 23:13 clutter-sharp
-rw-r--r-- 1 poissonbreaker poissonbreaker 429 2014-01-14 09:49 Dependencias
我只想获取日期字段 ($6) 与 2014-03 匹配的文件,这就是我对其进行简单 grep 的原因(目录中没有文件的文件名具有此模式):
ls -l | grep 2014-03
得出的结果是:
-rw-r--r-- 1 poissonbreaker poissonbreaker 0 2014-03-04 09:53 awk
-rw-r--r-- 1 poissonbreaker poissonbreaker 429 2014-01-14 09:49 Dependencias
然后我通过 awk 获取每个文件的文件名字段 ($8),最终将其移动到 build_tools 文件夹(此时我知道我的错误是什么了——build_tools 文件夹也在这个日期创建了 :S)。不过,我会把这个问题留在这里,以防其中某些部分对任何人都有用。
编辑 2:我已将 awk 表达式更改为:
awk '{if ($8!=build_tools) print $8}'
让它有意义。
答案1
我假设您有 GNU find
。如果您想移动在一定时间范围内(例如 2014 年 3 月)修改的文件或目录,请执行以下操作:
find . -maxdepth 1 \
-newermt 2014-02-28 -not -newermt 2014-04-01 \
-not -name 'build_tools' \
-exec mv {} build_tools \+
解释:
- 在此目录中查找,不包括子目录
- 2 月 28 日至 4 月 1 日之间的文件,其中
mt
表示修改时间。您也可以使用ct
它来搜索创建时间。 - 未命名的
build_tools
- 将它们全部移动到
build_tools
。这\+
意味着所有找到的文件/目录名称都将在 中替换{}
,而不是一次替换一个。如果您想要一次替换一个,则需要\;
。
有几件事:
不要解析输出
ls
。格式取决于操作系统,awk
如果文件/目录名称包含空格,则选择列会失败。您过去常常
&
连接命令,但&
只是将进程置于后台。如果可以的话,您应该使用&&
,但总的来说,实现您想要的效果会相当复杂。
答案2
我的解决方案的正确版本需要 xargs 来处理多个命令,这可以通过使用以下命令包装命令来实现:
sh -c (or bash -c) 'Command1; Command2; .. Comandn'
所以正确的解决方案是:
ls -l awk ' $8!=build_tools && $6 ~ /2013-03*/ {print $8}' | xargs -I @ sh -c 'mkdir build_tools/@; mv @ build_tools/@'
请注意,这会为每个要移动的文件创建一个新文件夹。
底线是,虽然其他人已经用更好、更专业的工具让我们的生活更轻松,但我们仍然可以从旧式管道查询中学到很多东西。至少对我来说是这样 :)