Как разбить строку на четыре строки - PullRequest
1 голос
/ 02 июня 2011

У меня большой файл журнала.В этом файле журнала у меня есть несколько строк, подобных этой

AgentID:5000|Glass Manufacturing|Seattle|36
AgentID:5000|Shoe Manufacturing|Las Vegas|31

Если я возьму grep для AgentID: 5000, я получу все записи, связанные с агентом 5000. Однако мне нужно разделить отчет следующим образом.

AgentID: 5000

Company Name: Glass Manufacturing
HeadQuarter: Seattle
Number of employees: 36

Company Name: Shoe Manufacturing
HeadQuarter: Las Vegas
Number of employees: 31

Это сервер Linux, где находится файл журнала, поэтому я могу использовать все приемы Linux.При необходимости я могу сделать сценарии на Perl или Ruby.

Как лучше всего начать.Я никогда не делал разбора текста раньше.Я слышал о awk и sed, но на самом деле не использовал его.

Просто ищу подходящие инструменты для решения этой проблемы.

Ответы [ 6 ]

0 голосов
/ 03 июня 2011

Никто еще не дал вам ответ awk, поэтому для полноты вот он:

awk -F'|' '
BEGIN { 
    print "AgentID: 5000\n"; 
} 
/^AgentID:5000|/ { 
    print "Company name: ", $2, "\nHeadquarters: ", $3, "\nNumber of employees:", $4, "\n"; 
}
' datafile
0 голосов
/ 03 июня 2011

Вот ваш скрипт, (не проверенный)

case "$#" in
    0|1) echo "Usage: $0 filename agent_id[s]"; exit 1;;
    *) file=$1; shift;;
esac

for wanted in "$@"
do
    echo "AgentID: $wanted"
    echo #empty line
    < "$file" grep "^AgentID *: *$wanted|" |(IFS=\|; while read id name hq num
        do
            echo "Company Name: $name"
            echo "HeadQuarter: $hq"
            echo "Number of employees: $num"
            echo #empty line
        done)
done
0 голосов
/ 03 июня 2011

Awk, sed и shell могут решить эту проблему, и это замечательное свидетельство коллективного гения оригинальных разработчиков Unix, что эти инструменты 1970-х годов до сих пор весьма ценны.

Но все же, если бы это была моя проблема, я бы просто пошел прямо к Perl или Ruby, как вы упомянули.

Вот реализация Ruby. ($ ruby whatever.rb < file)

E = [:'Company name', :'Headquarters', :'Number of employees']
T = Struct.new *E
while s = gets
  id, idn = fields = s.split(/[:|]/)
  puts "\nAgentID: " + idn unless idn == @idn
  puts
  @idn = idn
  line = T.new *fields[2..-1]
  puts E.map { |a| "#{a}: #{line[a]}" }
end
0 голосов
/ 03 июня 2011

Для этого я бы использовал макросы emacs. Смотрите "макросы" в:

http://swiss -knife.blogspot.com / 2007/11 / Emacs-выживание kit.html

0 голосов
/ 02 июня 2011

Все инструменты, которые вы перечислили, являются "правильными", но я бы, вероятно, выбрал параметр perl с модулем Text :: CSV cpan:

http://search.cpan.org/perldoc?Text%3A%3ACSV%3A%3ASeparator

Как видно из документации, труба (|) является одним из встроенных разделителей, доступных для обнаружения.

Вот еще одна ссылка на простой Perl-скрипт с разбором текста с использованием модуля:

http://www.joelbdalley.com/page.pl?29

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

0 голосов
/ 02 июня 2011
$ IFS='|' read id company hq empcount <<< 'AgentID:5000|Glass Manufacturing|Seattle|36'
$ echo "$id, $company, $hq, $empcount"
AgentID:5000, Glass Manufacturing, Seattle, 36

и BASH FAQ # 1 .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...