2016年10月27日 星期四

[轉貼] 在 Windows 批次刪除 N 天前的檔案

出處:http://blog.darkthread.net/post-2016-10-26-forfiles.aspx

工作上常遇到的需求:Log、暫存檔案多半有保留年限,如何用一個指令刪除某個期限前的舊檔?
今天才學到一個好用的 DOS 指令-forfiles,參數不多,簡單易用:
  • /p 路徑名稱 
    查詢對象,省略時為現在所處資料夾
  • /m 檔名限制 
    可配合萬用字元限定檔名或副檔名,例如:*.log、ex1610*.log
  • /s 
    指定搜尋範圍包含子目錄及其下層目錄
  • /c "對找到檔案執行的動作" 
    例如:"cmd /c del @path"為刪除檔案,省略參數時預設為"cmd /c echo @file",將顯示找到的檔案名稱
  • /d 數字或日期 
    限定檔案上次修改日期範圍,+代表大於等於,-代表小於等於,可以指定日期,例如:/d +2016/10/01(10/1當天及之後異動的檔案)、/d -2016/10/10(10/10當天與之前修改過的檔案);或指定數字今天起算幾天前的檔案,例如:/d -3(三天前)/d +0(今天)
撰寫 /c 參數時,有以下變數可用:
  • @file 檔名
  • @name 檔名去掉副檔名
  • @ext 副檔名
  • @path 完整路徑
  • @relpath 與 /p 為基準的相對路徑
  • @isdir 是否為資料夾
  • @fsize 檔案大小
  • @fdate 檔案上次修改日期
  • @ftime 檔案上次修改時間
所以刪除30天以前的Log檔可以寫成:
forfiles /p D:\Logs\IISLogs /s /m *.log /d –30 /c "cmd /c delete @path"
另外我也發現,forfiles 很適合解決之前提過將 DIR 結果轉為檔案清單的需求,還省去 Replace 計算相對路徑的功夫,是更好的選擇:
forfiles /p D:\Set9527 /s /c "cmd /c echo @relpath"
好物一枚,收入命令列工具箱。

2016年7月13日 星期三

[轉貼] 茅塞頓開的一晚-Func 委派+匿名方法+lambda

出處:https://dotblogs.com.tw/lastsecret/2010/06/26/16201

茅塞頓開的一晚-Func 委派+匿名方法+lambda
今天聽了同事講解Func,聽完覺得太酷了。
不過在紀錄之前,要先講一下 委派跟匿名方法。

委派在我自己的理解上,就是拜託他去幫你執行某個方法
當然拜託也要拜託對人,你所拜託的委派,要能做到你所要的方法(也就是傳回的型別,跟傳入的參數要一致)
這個想法還滿直觀的,例如現實中,你必須拜託某個朋友幫你挑女友的生日禮物
你一定挑個要嘛交過很多女朋友的人,不然就是挑個女生,比較懂該送甚麼
總不可能挑個阿宅,只想的到送遊戲點卡,還是漫畫之類的吧。當然修電腦找這種人不錯(我就是這個好人..)。
所以在建立委派時,這委派必須符合的你方法。
image

class Program
{
    static void Main(string[] args)
    {
        //讀進要做的動作" + , - , * , / "
        string s = Console.ReadLine();

        //建立一個委派
        MyDelegate d;

        //依照傳入的動作,選擇要傳入委派的方法
        switch (s)
        {
            case "+":
                d = new MyDelegate(加法);
                break;
            case "-":
                d = new MyDelegate(減法);
                break;
            case "*":
                d = new MyDelegate(乘法);
                break;
            case "/":
                d = new MyDelegate(除法);
                break;
            default:
                d = new MyDelegate(加法);
                break;
        }

        //使用該委派
        int Answer = d(5, 2);

        Console.WriteLine(Answer);
        Console.ReadKey();
    }

 //用static是因為我懶的new出物件,但要視情況用
    public static int 加法(int x, int y)
    {
        return (x + y);
    }

    public static int 減法(int x, int y)
    {
        return (x - y);
    }

    public static int 乘法(int x, int y)
    {
        return (x * y);
    }

    public static int 除法(int x, int y)
    {
        if (y != 0)
            return (x / y);
        return 0;
    }

    public delegate int MyDelegate(int x, int y);

}
上面的因為都是基本觀念,所以就咻咻咻的講完了。
接著講匿名方法,匿名方法就是不需要為了可能只用一次的方法
而建立類別實體和該方法,直接經由delegate關鍵字將方法傳入即可。
跟javascript的function有點類似,有時只用一次的function 就直接 xxx.click( function(){…})使用
因此改寫上面的Code 12~29行那段

switch (s)
{
    case "+":
        d = delegate(int x, int y)
        {
            return x + y;
        };
        break;
    case "-":
        d = (int x, int y) => { return x - y; };
        break;
    case "*":
        d = (int x,int y) => x * y;
        break;
    case "/":
        d = (x, y) => y != 0 ? x / y : 0;
        break;
    default:
        d = new MyDelegate(加法);
        break;
}
加法是用delegate關鍵字,然後傳入參數並在中括號中 return結果
減法省略delegate關鍵字,改用Lambda運算式的寫法
乘法連中括號和return都省了,直接寫要傳回的結果
除法連傳入的型別都可省略,因Lambda會自動推斷正確的型別
到這邊,就講完了委派、匿名方法,還提到一點Lambda了。
Lambda很好用,不過看起來太精簡所以有點難懂,基本格式是
(input parameters)  =>  { expression }
左邊想成傳入方法的參數,用  " => " 運算子連接,右邊是 方法的內容。

接著講 Func 這個東西
依照昨天為了打個球跟我在外面流浪一整晚的同事(他不想曝光)的說法,
Func是微軟定義好的delegate
因此他跟delegate一樣
可以替以他為型別的變數指派一個方法
可以替以他為型別的變數指派一個方法
可以替以他為型別的變數指派一個方法
可以替以他為型別的變數指派一個方法
來看一個例子

public static int MyFunc(Func<int, int, int> fun, int x, int y)
{
    return fun(x, y);
}
上面這個方法有三個參數,分別是 Func<int,int,int> fun, int x ,int y
第一個參數就是func,記得上面repeat好幾次的那句話嗎?Func可以替以他為型別的變數指派一個方法
所以就把 fun 當成一個可以 丟入方法的變數 來看,
而fun這個方法呢,要傳入兩個int型別的參數,並且回傳int型別的回傳值
image
接著看完整的範例

class Program
    {
        static void Main(string[] args)
        {
            string s = Console.ReadLine();

            Func<int, int, int> f;

            //   依照輸入的運算符號選擇要存的方法
            //   記得!!Func<>是可以存方法的變數,
            //   所以+我存了一個加法的方法
            //   -是用delegate存匿名方法
            //   *、/ 是用lambda存方法
            switch (s)
            {
                case "+":
                    f = 加法;
                    break;
                case "-":
                    f = delegate(int x, int y) { return x - y; };
                    break;
                case "*":
                    f = (int x, int y) => x * y;
                    break;
                case "/":
                    f = (x, y) => y != 0 ? x / y : 0;
                    break;
                default:
                    f = 加法;
                    break;
            }
            //使用MyFunc方法
            int answer = MyFunc(f, 5, 2);
            
            
            //也可以這樣寫喔,傳入匿名的Func
            //int answer = MyFunc((x, y) => x + y, 5, 5);
            
            
            Console.WriteLine(answer);
            Console.ReadKey();
        }

        public static int MyFunc(Func<int, int, int> fun, int x, int y)
        {
            return fun(x, y);
        }

        public static int 加法(int x, int y)
        {
            return (x + y);
        }
    }
呼,講完了。
整個過程不太好懂,因為等於是方法中又有方法。
但懂了之後,覺得有很趣。

雖然現在經驗不足,還不知道要用在哪裡比較適當,但學起來再說。