How to split a line into four lines
I have a large log file. In this log file I have some lines like this
AgentID:5000|Glass Manufacturing|Seattle|36
AgentID:5000|Shoe Manufacturing|Las Vegas|31
If I grep for AgentID:5000 then I will get all the records related to Agent 5000. However I need to split the report like this.
AgentID: 5000
Company Name: Glass开发者_StackOverflow中文版 Manufacturing
HeadQuarter: Seattle
Number of employees: 36
Company Name: Shoe Manufacturing
HeadQuarter: Las Vegas
Number of employees: 31
It is a linux server where the log file is so I can use all linux tricks. If needed I can do perl or ruby scripting.
What is the best way to get started. I have never done text parsing before. I have heard about awk and sed but haven't really used it.
Just looking for the right tools to solve this problem.
$ IFS='|' read id company hq empcount <<< 'AgentID:5000|Glass Manufacturing|Seattle|36'
$ echo "$id, $company, $hq, $empcount"
AgentID:5000, Glass Manufacturing, Seattle, 36
And BASH FAQ entry #1.
All the tools you've listed are the "right" ones but I would probably go for the perl option with maybe the Text::CSV cpan module:
http://search.cpan.org/perldoc?Text%3A%3ACSV%3A%3ASeparator
As you can see in the documentation, a pipe (|) is one of the built in delimiters available for detection.
Here's another link to a simple perl script with some text parsing utilizing the module:
http://www.joelbdalley.com/page.pl?29
No doubt, there will be lots of other examples easily found.
For this I would use emacs macros. See "macros" in:
http://swiss-knife.blogspot.com/2007/11/emacs-survival-kit.html
Awk, sed, and the shell can all solve this problem, and it's a remarkable testament to the collective genius of the original Unix implementors that those 1970's tools are still quite valuable today.
But still, if it were my problem, I would just go straight to Perl or Ruby, as you mentioned.
Here is a Ruby implementation. ($ 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
No-one has given you the awk
answer yet, so for completeness here it is:
awk -F'|' '
BEGIN {
print "AgentID: 5000\n";
}
/^AgentID:5000|/ {
print "Company name: ", $2, "\nHeadquarters: ", $3, "\nNumber of employees:", $4, "\n";
}
' datafile
Here is your script, (not tested)
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
精彩评论