Как обнаружить EOF в awk?

Я расширил решение Мартина Мерфи и надеюсь, что оно сработает в каждом случае.

private static string DecodeQuotedPrintables(string input, string charSet)
{           
    if (string.IsNullOrEmpty(charSet))
    {
        var charSetOccurences = new Regex(@"=\?.*\?Q\?", RegexOptions.IgnoreCase);
        var charSetMatches = charSetOccurences.Matches(input);
        foreach (Match match in charSetMatches)
        {
            charSet = match.Groups[0].Value.Replace("=?", "").Replace("?Q?", "");
            input = input.Replace(match.Groups[0].Value, "").Replace("?=", "");
        }
    }

    Encoding enc = new ASCIIEncoding();
    if (!string.IsNullOrEmpty(charSet))
    {
        try
        {
            enc = Encoding.GetEncoding(charSet);
        }
        catch
        {
            enc = new ASCIIEncoding();
        }
    }

    //decode iso-8859-[0-9]
    var occurences = new Regex(@"=[0-9A-Z]{2}", RegexOptions.Multiline);
    var matches = occurences.Matches(input);
    foreach (Match match in matches)
    {
        try
        {
            byte[] b = new byte[] { byte.Parse(match.Groups[0].Value.Substring(1), System.Globalization.NumberStyles.AllowHexSpecifier) };
            char[] hexChar = enc.GetChars(b);
            input = input.Replace(match.Groups[0].Value, hexChar[0].ToString());
        }
        catch { }
    }

    //decode base64String (utf-8?B?)
    occurences = new Regex(@"\?utf-8\?B\?.*\?", RegexOptions.IgnoreCase);
    matches = occurences.Matches(input);
    foreach (Match match in matches)
    {
        byte[] b = Convert.FromBase64String(match.Groups[0].Value.Replace("?utf-8?B?", "").Replace("?UTF-8?B?", "").Replace("?", ""));
        string temp = Encoding.UTF8.GetString(b);
        input = input.Replace(match.Groups[0].Value, temp);
    }

    input = input.Replace("=\r\n", "");
    return input;
}
10
задан user3562 29 October 2009 в 21:22
поделиться

4 ответа

У вас есть два варианта, оба беспорядочные.

  1. Сохраните копию каждой текущей строки во временной переменной, а затем используйте блок END для ее обработки.
  2. Используйте системную команду, чтобы запустить «wc -l | getline» в блоке BEGIN, чтобы получить количество строк в файле, а затем подсчитайте это значение.

Возможно, вам придется немного поиграть с №2, чтобы заставить его работать, но он должен работать. Давненько я не делал awk.

9
ответ дан 3 December 2019 в 14:11
поделиться

Хм, переменная awk END сообщает, когда вы уже достигли EOF . Думаю, тебе не особо поможет

0
ответ дан 3 December 2019 в 14:11
поделиться

Специальный шаблон END будет соответствовать только после окончания всего ввода . Обратите внимание, что этот шаблон нельзя комбинировать ни с каким другим шаблоном.

Более полезной, вероятно, является псевдофункция getline , которая сбрасывает $ 0 на следующую строку и возвращает 1, или в случае EOF возврат 0! Думаю, это именно то, что вам нужно.

Например:

awk '{ if(getline == 0) { print "Found EOF"} }'

Если вы обрабатываете только один файл, это будет эквивалентно:

awk 'END { print "Found EOF" }'
11
ответ дан 3 December 2019 в 14:11
поделиться

Я даже не уверен, как классифицировать это «решение»

{
    t = lastline
    lastline = $0
    $0 = t
}

/test/ {
    print "line <" $0 "> had a _test_"
}

END {
    # now you have "lastline", it can't be processed with the above statements
    # ...but you can work with it here
}

. Самое замечательное в этом хаке - это то, что, назначив $ 0 , все остальные декларативные шаблоны и действия работают, одна строчка задерживается. Вы не можете заставить их работать для END , даже если вы поместите END вверху, но вы контролируете последнюю строку, и вы больше ничего не сделал.

2
ответ дан 3 December 2019 в 14:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: