shaz shaz - 7 months ago 17
Bash Question

shell script to format text, merge lines, add tabs

20140918-17:31:19.835
34=11
52=20140918-17:31:19.812
273=17:31:19.797
273=17:31:19.797
273=17:31:19.797
273=17:31:19.797
20140918-17:31:19.837
34=12
52=20140918-17:31:19.813
273=17:31:19.797
273=17:31:19.797
273=17:31:19.797
273=17:31:19.797
20140918-17:31:19.838
34=13
52=20140918-17:31:19.813
273=17:31:19.797
273=17:31:19.797
273=17:31:19.797
273=17:31:19.797


I have this input and want to format it like this:

34=11 20140918-17:31:19.835
52=20140918-17:31:19.812
273=17:31:19.797
273=17:31:19.797
273=17:31:19.797
273=17:31:19.797
34=12 20140918-17:31:19.837
52=20140918-17:31:19.813
273=17:31:19.797
273=17:31:19.797
273=17:31:19.797
273=17:31:19.797
34=13 20140918-17:31:19.838
52=20140918-17:31:19.813
273=17:31:19.797
273=17:31:19.797
273=17:31:19.797
273=17:31:19.797


I have no shell scripting experience, I'm afraid this question might be inappropriate but if you could point me to a good shell scripting tutorial that would get me started I'd appreciate it!

Answer

You can do this using awk:

awk '!/=/{m=$0; next}m{$0=$0 FS m; m=0}/^52=/{$0="\t"$0}/^273=/{$0="\t\t"$0}1' file

How it works:

  • !/=/{m=$0; next} - If the line doesn't contain =, the line record ($0) is assigned to the m variable. next skips to the next line as no further processing is needed.

  • m{$0=$0 FS m; m=0} - If m is defined (greater than zero), append the current line ($0) with the field separator (FS) and the variable m (previous line). Finally, reset the m variable to zero as we need to make sure this code block keeps getting executed immediately after the line that does not contain an = character.

  • /^52=/{$0="\t"$0} - If the current line starts with 52=, prefix the current line record ($0) with a tab character (\t)

  • /^273=/{$0="\t\t"$0} - If the current line starts with 273=, prefix the current line record with two tab characters.

  • 1 - This is just a little shorthand trick for saying {print} regardless of any condition. The 1 is just telling awk print is true. You could really substitute anything truthy for this and it would do the same thing since awk's default action is to print if a condition is true and no following code block is provided.

On any UNIX system, awk is the go to language for manipulating text files.

I've found this intro to be exceptionally concise. Also, awk.info has a wide collection of overviews and tutorials. As far as documentation goes, the GNU Awk User's Guide is pretty comprehensive.

Comments