2015-10-21 64 views
0

我在这个shell脚本中仍然是新的。我有一项给予我的任务,我很难执行它。 任务是我有很多基于ddmmyy的目录。c shell脚本:找到目录并重命名find的输出

03Mar2014 08Aug2013 11Jan2015 16Jan2014 22Feb2014 26Mar2014 
03Nov2013 08Jan2014 11Jul2013 16Jul2013 22Jul2013 26Oct2014 
03Oct2013 08Jan2015 11Nov2014 16May2014 22Mar2014 26Sep2013 

任务是使目录变为mmyy。

到目前为止,我的代码是

foreach file(`find . -type d | awk -F/ 'NF == 3'`) 
echo $file 
set newmove = `echo $file | cut -c 1-2,5-` 
echo $newmove 
mv $file $newmove 

output: 
for find . -type d | awk -F/ 'NF == 3': 
./24Jan2015/W51A 
`echo $file | cut -c 1-2,5-` 
./Jan2015/W51A 
mv $file $newmove 
mv: cannot rename ./24Jan2015/W51A to ./Jan2015/W51A: No such file or directory 

,但剧本没有工作。 你们有什么想法如何做到这一点?

+0

*必须*你使用c-shell来做这件事,或者你可以交替使用POSIX shell或Bash?另外,当你想制作目录“mmyy”时,你真的是指“mmmYYYY”,就像你显示的输入列表一样吗? [CSH编程有时被认为是有害的。](http://www.bmsc.washington.edu/people/merritt/text/cshbad.txt) – ghoti

回答

0

首先,问题是你重命名文件,但实际上试图重命名目录,因此错误。

正如我理解的想法是重新命名当前工作目录所需格式的文件夹,并通过这实际上合并的文件夹从同一mmYYYY格式到新的(内容自11Jan201516Jan2014将两者更名为Jan2014

你可以试试这个:

foreach dir (`ls`)  
    set newdir = `echo $dir| cut -c 3-` 

    mkdir -p $newdir 
    mv -f $dir/* $newdir 
    rmdir $dir 
end 

-p将创建文件夹,如果该文件夹已经存在,不会做任何事情。

一些假设:

  1. 的文件夹是在这pwd
  2. 总是有日起的前几位数字相同的地方
  3. 你想在同一mmYYYY格式
  4. 的文件夹的内容合并
  5. 在不同文件夹中具有相同名称的文件将被覆盖
  6. 只有pwd中的文件夹(添加检查是否不是这种情况)

如果这些文件夹在不同的地方(这是不是根据你的输出的情况下:./24Jan2015)和碰撞是不是一个问题 - 该代码应改为:

  1. 使用发现
  2. 使用正确的路径创建新的文件夹

没有合并并覆盖会发生,所以1,3,4和5是不相关的。

UPDATE: 额外的输入之后 - 如果我理解正确你找到的是只想找深度3的文件夹,我不能说为什么,但你可以用

find . -type d -mindepth=2 -maxdepth=2 

的更快达到同样的输出是具有子文件夹的文件夹的列表。

然后,您需要获取第二个文件夹的名称(假设它将始终是预期的格式)。

set olddir = `echo $file| cut -f 1-3 -d '/'` 
set newdir = `echo $olddir | cut -c 1-2,5-` 

最后

foreach file(`find . -type d -mindepth=2 -maxdepth=2`) 
    set olddir = `echo $file| cut -f 1-3 -d '/'` 
    set newdir = `echo $olddir | cut -c 1-2,5-` 

     mkdir -p $newdir 
     mv -f $file $newdir 
end 

这也将处理,如果两个文件夹中的同一路径下找到的情况。

更新2:

由于脚本将在Unix上运行 - 下面的更新应该进行:

  • 由于UNIX找到原始的发现被退回缺乏mindepth/MAXDEPTH选项
  • 我们应该尝试删除olddir以清除空文件夹 - 如果该文件夹不是空的但文件应该继续运行,则会失败
foreach file(`find . -type d | awk -F/ 'NF == 3'`) 
    set olddir = `echo $file| cut -f 1-2 -d '/'` 
    set newdir = `echo $olddir | cut -c 1-2,5-` 
    set dir_name=`basename "$file"` 


     if (-d "$newdir/$dir_name") then 
      mv -f $file/* $newdir/$dir_name/ 
     else 
     mkdir -p $newdir 
     mv -f $file $newdir 
     endif 
    rmdir $olddir 
end 
+0

谢谢。基于我的脚本,我已经使用find,以便有不同的路径。那么在删除dd后如何制作目录如果他们有相同的目录? – wina

+0

如果您想在创建原始文件夹的位置创建它,那么您不会遇到问题,因为路径不同。否则,如果你想移动到特定的位置 - 使用脚本'$ some_place/$ new_dir'而不是'$ new_dir',其中'some_place'是特定路径 –

+0

已更新。但请注意,您没有找到不同的路径,只能查看密码文件夹中的文件夹。 –

0

我真的认为c shell对于任何涉及编程的东西都是错误的工具。这就是说,这看起来像它会做你想要从外部工具只有一点点的帮助:

#!/bin/csh 

foreach file ([0-9][0-9][A-Z][a-z][a-z][0-9][0-9][0-9][0-9]) 
    set new = `echo $file:q | cut -c 3-` 
    if (-d "$new") then 
    echo "skipping $file because $new already exists" 
    continue 
    endif 
    mv -v "$file" "$new" 
end 

注意符合您的目录重命名列表的水珠。这个脚本并不打算确认匹配的文件是否实际上是目录,所以如果有可能它们不可能,你应该以某种方式解释它。

请注意,我们使用反引号表达式来使用外部工具cut从每个目录名称中获取子字符串。我们使用这个(就像你在你的问题中所做的那样),因为CSH不是一种编程语言,并且没有它自己的字符串处理能力。

循环中的if语句将跳过其目标已存在的任何目录。举例来说,如果您要在您的问题中查看输入的第一行,2014年4月26日将转换为2014年3月,该日期已于2014年3月3日之前存在。由于您尚未指定应如何处理,因此此脚本会跳过该情况。

+0

非法选项--v。 – wina

+0

@wina,'--v'不是我使用的选项,尝试一个短划线,这在BSD,OSX和Linux中是一个有效的选项,如果你使用的是某些否则,请说出来,或者放弃选项。 – ghoti

+0

即时通讯使用单破折号诉出错是\t 非法选项--v – wina