c shell脚本:查找目录并重命名find的输出

时间:2015-10-21 03:44:59

标签: shell find rename

我仍然是这个shell脚本的新手。我有一项任务给了我,我很难执行它。 任务是我有很多基于ddmmyy的目录。

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

但脚本没有用。 你们有任何想法怎么做吗?

2 个答案:

答案 0 :(得分:0)

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

据我所知,我的想法是将当前工作目录中的文件夹重命名为所需的格式,然后实际将文件夹的内容从相同的mmYYYY格式合并到新的格式(自 11Jan2015 16Jan2014 将重命名为 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. 日期总是有两个前导数字
  4. 您想要合并相同mmYYYY格式的文件夹内容
  5. 将覆盖不同文件夹中具有相同名称的文件
  6. pwd中只有文件夹(添加检查是否不是这样)
  7. 如果这些文件夹位于不同的位置(根据您的输出不是这种情况: ./ 24Jan2015 )并且碰撞不是问题 - 代码应更改为:

    1. 使用find
    2. 使用正确的路径创建新文件夹
    3. 不会发生合并和覆盖,因此1,3,4和5不相关。

      更新: 在额外输入之后 - 如果我理解正确,您的查找仅查找深度为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 find缺少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
      

答案 1 :(得分: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

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

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

循环中的if语句将跳过目标已存在的任何目录。例如,如果您要在问题中查看输入的第一行,26Mar2014将转换为2014年3月,由于03Mar2014已经存在。由于您尚未指定应如何处理此脚本,因此该脚本会跳过该条件。