我仍然是这个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
但脚本没有用。 你们有任何想法怎么做吗?
答案 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将创建该文件夹,如果该文件夹已存在,则不执行任何操作。
一些假设:
pwd
如果这些文件夹位于不同的位置(根据您的输出不是这种情况: ./ 24Jan2015 )并且碰撞不是问题 - 代码应更改为:
不会发生合并和覆盖,因此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上运行 - 应进行以下更新:
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已经存在。由于您尚未指定应如何处理此脚本,因此该脚本会跳过该条件。