четверг, 3 января 2008 г.

Забавы с Linq

Навеяно дискуссией в RSDN MIT переходи со схемы на...

Разговор каким-то образом перекинулся на краткость которая сестра таланта и bash.
самопроизвольно возникла задача переписать вот такую команду
grep -h USER *.log | gawk "{ print $2 }" | sort | uniq

на Немерле.

В результате получилось вот что:

using Nemerle.List;

using System.IO.Directory;

using System.IO.File;

 

def search = "USER";

def files = GetFiles(folder).ToList().Filter(_.EndsWith(".log"));

def lines = Flatten(files.Map(ReadAllLines(_).ToList().Filter(_.Contains(search)));

def lines = lines.Map(line => line.Substring(line.IndexOf(search) + search.Length));

def lines = lines.Sort().RemoveDuplicates();



Интереса ради решил переписать этот пример с использованием Linq.
Вот что получилось (отбрасывая всякие using и прочее):

var x = (from n in Directory.GetFiles(@"D:\temp\!!!") where n.EndsWith(".log")

        from line in n.LinesFromFile() where line.Contains("USER")

        orderby line  select line).Distinct();


Результат не совсем "чистый" поскольку стандартной функции LinesFromFile нет. Пришлось написать свою. Поэтому для полноты картины стоит наверно также добавить код этой функции. Вообщем в целом код (включая заголовок) выглядит следующим образом:

using System;

using System.Collections.Generic;

using System.Linq;

using System.IO;

 

 

namespace test_bash

{

    public static class StreamReaderSequence

    {

        public static IEnumerable<string> LinesFromFile(this string path)    {

            using (StreamReader source = new StreamReader(path)){

                String line;

                while ((line = source.ReadLine()) != null)

                    yield return line;

            }

        }

    }

 

    class Program

    {

        static void Main(string[] args)    {

            var x = (from n in Directory.GetFiles(@"D:\temp\!!!") where n.EndsWith(".log")

                    from line in n.LinesFromFile() where line.Contains("USER")

                    orderby line  select line).Distinct();

 

            foreach (var i in x)

                Console.WriteLine(i);

        }

    }

}

Комментариев нет: