2015-10-21 63 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