The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]




Версия для распечатки Пред. тема | След. тема
Новые ответы [ Отслеживать ]
AWK SPLIT, !*! SLario, 04-Сен-09, 12:44  [смотреть все]
Уважаемые коллеги!

Я пишу скрипт, который должен перебрать все файлы из списка и разобрать с помощью split имя каждого файла. Я делаю это так:

for file in `cat /$FileListFN`; do
     echo `awk   '
                 {N=split(FILENAME,FNParts,"_")}
                 {for (i=1; i<=N; i++)
                    {print FNParts[i] " | "}
                 }
                 ' $file`
done

При запуске я получаю что-то странное - из списка

BD52_New_28_04_09.xml
BD5A_New_28_04_09.xml
BD62_New_28_04_09.xml
BD6A_New_28_04_09.xml
BD72_New_28_04_09.xml
BD7A_New_28_04_09.xml
BD82_New_28_04_09.xml
BD8A_New_28_04_09.xml

получается такой вывод:

BD52 | New | 28 | 04 | 09.xml | BD52 | New | 28 | 04 | 09.xml | BD52 | New | 28 | 04 | 09.xml |
BD5A | New | 28 | 04 | 09.xml | BD5A | New | 28 | 04 | 09.xml | BD5A | New | 28 | 04 | 09.xml |
BD62 | New | 28 | 04 | 09.xml | BD62 | New | 28 | 04 | 09.xml | BD62 | New | 28 | 04 | 09.xml |
BD6A | New | 28 | 04 | 09.xml | BD6A | New | 28 | 04 | 09.xml | BD6A | New | 28 | 04 | 09.xml |
BD72 | New | 28 | 04 | 09.xml | BD72 | New | 28 | 04 | 09.xml | BD72 | New | 28 | 04 | 09.xml |
BD7A | New | 28 | 04 | 09.xml | BD7A | New | 28 | 04 | 09.xml | BD7A | New | 28 | 04 | 09.xml |
BD82 | New | 28 | 04 | 09.xml | BD82 | New | 28 | 04 | 09.xml | BD82 | New | 28 | 04 | 09.xml |
BD8A | New | 28 | 04 | 09.xml | BD8A | New | 28 | 04 | 09.xml | BD8A | New | 28 | 04 | 09.xml |

Почему строка утраивается? Мой скрипт аналогичен примерам, но там всё работает, как надо...

Система - Solaris.

  • AWK SPLIT, !*! allez, 14:09 , 04-Сен-09 (1)
    >Уважаемые коллеги!
    >
    >Я пишу скрипт, который должен перебрать все файлы из списка и разобрать
    >с помощью split имя каждого файла.

    Использование split обязательно? Такой вариант не подойдет?

    $ echo "BD8A_New_28_04_09.xml" | awk -F "_" '{for (i=1; i<=NF-1; i++) {printf $i " | "} print $NF}'
    BD8A | New | 28 | 04 | 09.xml

    • AWK SPLIT, !*! SLario, 14:51 , 04-Сен-09 (2)
      Уважаемый allez, дело в том, что мне надо заполучить эту информацию в массиве. Запланирована обработка XML, в структуру которого будет вставлено разобранное по шаблону имя файла. Идея такая - разобрать имя файла в массив FNPart, шаблон вида "ID_Action_DD_MM_YY.xml" в массив Tags, потом создать такую строку: <Tag[1]><FNPart[1]></Tag[1]> ... <Tag[n]><FNPart[n]></Tag[n]> и вставить её в очередной XML (там запись в одну строку, поэтому можно вставить сгенерённую строчку между первыми найденными ><)
  • AWK SPLIT, !*! Andrey Mitrofanov, 14:57 , 04-Сен-09 (3)
    >for file in `cat /$FileListFN`; do
    >     echo `awk   '
    >     {N=split(FILENAME,FNParts,"_")}
    >     {for (i=1; i<=N; i++)
    >        {print FNParts[i] " | "}
    >     }
    >     ' $file`

    $ echo "BD8A_New_28_04_09.xml" | gawk '{N=split($0,FNParts,"_"); for (i=1; i<=N; i++) {printf FNParts[i] " | "};print "";exit }'
    BD8A | New | 28 | 04 | 09.xml |
    $ gawk -v f="BD8A_New_28_04_09.xml" 'BEGIN{N=split(f,FNParts,"_"); for (i=1; i<=N; i++) {printf FNParts[i] " | "};print"";exit }'
    BD8A | New | 28 | 04 | 09.xml |
    $ echo "BD8A_New_28_04_09.xml" | sed 's/_/ | /g'
    BD8A | New | 28 | 04 | 09.xml
    $ _

    >Почему строка утраивается?

    Потому что FILENAME - не только имя файла, но и... "три! четыре!! килограмма..." ...чтение его построчно. Утраивается -- потому, что три строки в соотв.файлах.

    >Система - Solaris.

    Соболезнования. Мужайтесь.

    • AWK SPLIT, !*! SLario, 15:06 , 04-Сен-09 (4)
      >>Почему строка утраивается?
      >
      >Потому что FILENAME - не только имя файла, но и... "три! четыре!!
      >килограмма..." ...чтение его построчно. Утраивается -- потому, что три строки в
      >соотв.файлах.
      >

      Да, точно, в тех XML-файлах по три строки... В предыдущем ответе я описал задачу, которую надо решить, м.б., это можно сделать как-то проще?

      • AWK SPLIT, !*! Andrey Mitrofanov, 15:15 , 04-Сен-09 (5)
        >м.б., это можно сделать как-то проще?

        Можно, я не возражаю.

        {printf FNParts[i] " | "}
        -->
        {print "<Tag["i"]>" FNParts[i] "</Tag["i"]>"}
        или
        {print "<"Tag[i]">"FNParts[i]"</"Tag[i]">"}

        • AWK SPLIT, !*! SLario, 15:19 , 04-Сен-09 (6)
          Ух ты, шикарно! Тогда ещё вопрос: шаблон имени файла задаётся переменной скрипта $FileNameTemplate немного выше по тексту (не попало в мою копипасту). Массив должен быть сформирован из него. Можно ли запихнуть в AWK обработку переменной скрипта?

          Пока я догадался делать это вот так:

          FileNameTemplate="ID_Action_DD_MM_YY"

          for file in `cat /$FileListFN`; do
             XMLInsertion=`echo $FileNameTemplate | awk '{N=split($0,Tags,"_")}{split(FILENAME,FNParts,"_")}{for (i=1; i<=N; i++) {print <Tags[i]><FNParts[i]><\Tags[i]>}}' $file`
             echo $XMLInsertion
          done

          Но это падает с ошибкой синтаксиса.

          • AWK SPLIT, !*! Andrey Mitrofanov, 16:14 , 04-Сен-09 (7)
            >Ух ты, шикарно!

            Ну, да, мастерство не пропьёшь. B)

            Тогда ещё вопрос: шаблон имени файла задаётся переменной скрипта
            >$FileNameTemplate немного выше по тексту (не попало в мою копипасту). Массив
            >должен быть сформирован из него. Можно ли запихнуть в AWK обработку
            >переменной скрипта?

            Ещё раз, внимательно:
            ""не только имя файла, но и... "три! четыре!! килограмма..." ...чтение его построчно""

            =Почитай, чего awk делает с входным файлом (бишь stdin-ом). Это в "man awk", где-то там. Или man nawk, или man mawk, или man gawk... В любом из них. Главное найти - два абзаца примерно.

            >
            >Пока я догадался делать это вот так:
            >FileNameTemplate="ID_Action_DD_MM_YY"
            >
            >for file in `cat /$FileListFN`; do
            >   XMLInsertion=`
            >Но это падает с ошибкой синтаксиса.

            С кавычками (экранированием спец.символов) всё _очень_ плохо.

            Пятница... Семья не ждёт?..

            FileNameTemplate="ID_Action_DD_MM_YY"

            cat /$FileListFN \
            awk 'BEGIN{сделать_из_строки_массив_tag("'"$FileNameTemplate"'"}
            '{N=split($0,FNParts,"_")
            printf $0" "
            for (i=1; i<=N; i++) {
            printf "<"Tag[i]">"FNParts[i]"</"Tag[i]">"
            };print"";exit }' |\
            while read filename xfragment; do
              # работать с $filename + $xfragment ...
            done

            • AWK SPLIT, !*! SLario, 10:12 , 07-Сен-09 (9)
              Интересно, можно ли как-нибудь ограничить набор входных строк и обрабатывать, например, только первую строку? Таким образом я смог бы убить все повторы, т.к., будет обрабатываться ровно одна строка. Я написал такое условие на входе:

              for file in `cat /$FileListFN`; do
                 echo `awk  'NR==1
                             {N=split(FILENAME,FNParts,"_")}
                             {for (i=1; i<=N; i++)
                                {print FNParts[i]}
                             }' $file`
                 echo $XMLInsertion
              done

              , но оно не привело ни к чему хорошему - просто в случае выполнения шаблона выводится первая строка файла и все повторы из моего самого первого вопроса...

              • AWK SPLIT, !*! SLario, 15:30 , 09-Сен-09 (12)
                >Интересно, можно ли как-нибудь ограничить набор входных строк и обрабатывать, например, только
                >первую строку?

                Решено использованием оператора {exit}.

            • AWK SPLIT, !*! SLario, 12:21 , 07-Сен-09 (11)
              Андрей, приветствую!

              А что означает
              awk 'BEGIN{сделать_из_строки_массив_tag("'"$FileNameTemplate"'"}? Мне не удалось заставить скрипт заработать...

          • AWK SPLIT, !*! mx3ix, 16:22 , 04-Сен-09 (8)
            >[оверквотинг удален]
            >Пока я догадался делать это вот так:
            >
            >FileNameTemplate="ID_Action_DD_MM_YY"
            >
            >for file in `cat /$FileListFN`; do
            >   XMLInsertion=`echo $FileNameTemplate | awk '{N=split($0,Tags,"_")}{split(FILENAME,FNParts,"_")}{for (i=1; i<=N; i++) {print <Tags[i]><FNParts[i]><\Tags[i]>}}' $file`
            >   echo $XMLInsertion
            >done
            >
            >Но это падает с ошибкой синтаксиса.

            Вопрос не понятен. Очень сложный слог изложения. Не прослеживается формализация задачи. Но, все-таки, попробую помочь.

            Передача параметров в AWK (это написано в MAN и неоднократно проверено на практике) осуществляется посредством -v параметра. Например:

            awk -f MyMegaSuperAWKScript.awk -v FileNameTemplate=$MYMEGASUPERSHELLVARIABLE

            После чего внутри скрипта все это обрабатывается. С содержанием скрипта не смогу помочь, так как задача изложена невразумительно (с моей точки зрения).

            • AWK SPLIT, !*! SLario, 12:11 , 07-Сен-09 (10)
              Приветствую!
              Ниже распишу задачу более подробно. Надо слить несколько однотипных XML-файлов в один большой XML, не потеряв при этом информацию об исходных файлах. Сохранять информацию предлагается в дополнительных тегах, которые добавятся в основной текст. Исходные XML-файлы представляют собой длинные строки, т.е., в первой строке лежит заголовок XML, а в следующих - записи XML, по одной записи на строку. Идея такая - шаблон имени файла (из входного параметра) разобрать в один массив Tag, имя текущего файла разобрать в другой массив FNPart, потом склеить из них XML-подобную строку вида
              <Tag[1]><FNPart[1]></Tag[1]> ... <Tag[n]><FNPart[n]></Tag[n]>,
              после этого выкинуть из очередного файла строку №1 (с заголовком) и работать только с остальными, заменяя в них самое первое вхождение сочетания >< на ><Tag[1]><FNPart[1]></Tag[1]> ... <Tag[n]><FNPart[n]></Tag[n]><. Этим я добьюсь добавления в текуший файл XML информации о названии этого файла. А потом я возьму шаблон заголовка (заголовок XML + открывающий общий тег), прилью к нему полученные строки из разных файлов XML с внедрённой информацией и закрою файл шаблоном подвала XML (закрывающий общий тег). Таким образом получается, что надо два раза использовать split, затем выводить результат склеивания в переменную shell, затем sed будет менять (начиная со второй строки) первое вхождение >< и менять его на >переменная<. Пока я завис на этапе ввода в awk переменной скрипта, хранящей шаблон имени файла. Подключенная внешняя переменная не видится в программе awk:

              for file in `cat /$FileListFN`; do
                 echo `awk  '{print $FNT}
                             {N=split($FNT,Tags,"_")}
                             {for (i=1; i<=N; i++)
                               {print Tags[i] " | "}
                             }    
                             {exit}
                             ' $file -v FNT=$FileNameTemplate`
              done

              {exit} нужен для того, чтобы обрабатывать всё только один раз. Этот скрипт почему-то ничего не выводит, ждёт ввода с клавиатуры...

              • AWK SPLIT, !*! SLario, 15:32 , 09-Сен-09 (13)
                Выяснил, что внутри awk-скрипта не надо писать $ перед именем переменной. Задача успешно решена, всем участникам обсуждения большое спасибо!





Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру