28

Would awk be useful to convert "Input" to "Desired output"?

Input

testing speed of encryption
test 0 (64 bit key, 16 byte blocks): 2250265 operations in 1 seconds (36004240 bytes)
test 1 (128 bit key, 64 byte blocks): 879149 operations in 1 seconds (56265536 bytes)
test 2 (128 bit key, 256 byte blocks): 258978 operations in 1 seconds (66298368 bytes)
test 3 (128 bit key, 1024 byte blocks): 68218 operations in 1 seconds (69855232 bytes)
test 4 (128 bit key, 8192 byte blocks): 8614 operations in 1 seconds (70565888 bytes)
test 10 (256 bit key, 16 byte blocks): 1790881 operations in 1 seconds (3654096 bytes)

Desired output

testing speed of encryption
test  0  (64 bit key,   16 byte blocks): 2250265 operations in 1 seconds (36004240 bytes)
test  1 (128 bit key,   64 byte blocks):  879149 operations in 1 seconds (56265536 bytes)
test  2 (128 bit key,  256 byte blocks):  258978 operations in 1 seconds (66298368 bytes)
test  3 (128 bit key, 1024 byte blocks):   68218 operations in 1 seconds (69855232 bytes)
test  4 (128 bit key, 8192 byte blocks):    8614 operations in 1 seconds (70565888 bytes)
test 10 (256 bit key,   16 byte blocks): 1790881 operations in 1 seconds  (3654096 bytes)

3 Answers 3

47

A trick to align right using column is to use rev:

$ head -1 file; tail -n+2 file | rev | column -t | rev
testing speed of encryption
test   0   (64  bit  key,    16  byte  blocks):  2250265  operations  in  1  seconds  (36004240  bytes)
test   1  (128  bit  key,    64  byte  blocks):   879149  operations  in  1  seconds  (56265536  bytes)
test   2  (128  bit  key,   256  byte  blocks):   258978  operations  in  1  seconds  (66298368  bytes)
test   3  (128  bit  key,  1024  byte  blocks):    68218  operations  in  1  seconds  (69855232  bytes)
test   4  (128  bit  key,  8192  byte  blocks):     8614  operations  in  1  seconds  (70565888  bytes)
test  10  (256  bit  key,    16  byte  blocks):  1790881  operations  in  1  seconds   (3654096  bytes)
Sign up to request clarification or add additional context in comments.

1 Comment

nice. However, this doesn't work if the last column has non-constant width.
24

Yes. Look at the syntax for awk's printf() function. Abbreviated sample code . . .

{
  printf("%s %2s ", $1, $2);
  printf("%4s %s %s ", $3, $4, $5);
  printf("%4s %s %s ", $6, $7, $8);
  printf("%7s\n", $9);
}

Output.

test  0  (64 bit key,   16 byte blocks): 2250265
test  1 (128 bit key,   64 byte blocks):  879149
test  2 (128 bit key,  256 byte blocks):  258978
test  3 (128 bit key, 1024 byte blocks):   68218
test  4 (128 bit key, 8192 byte blocks):    8614
test 10 (256 bit key,   16 byte blocks): 1790881

Docs for GNU awk's printf().

There are several ways to pass the "heading" through unmodified. This way assumes it's always on the first line of the file.

NR==1 { print $0}
NR>1 {
  printf("%s %2s ", $1, $2);
  printf("%4s %s %s ", $3, $4, $5);
  printf("%4s %s %s ", $6, $7, $8);
  printf("%7s\n", $9);
}

4 Comments

Very interesting! Is it possible to have the header pass through without being aligned?
As far as I can tell, this doesn't work reliably with strings with multibyte characters as the width modifier (4 in %4s) is counting bytes instead of what most people would consider "characters"
It counts characters on my box. Is your terminal Unicode-aware?
Good, because the column command can't handle large files (like 6GB or more).
8
awk '
FNR==1 { if (NR==FNR) print; next }
NR==FNR {
   for(i=1;i<=NF;i++)
      w[i] = (w[i] <= length($i) ? length($i) : w[i])
   next
}
{
   for(i=1;i<=NF;i++)
      printf "%*s",w[i]+(i>1?1:0),$i
   print ""
}
' file file

1 Comment

I think it should be if (NR==FNR) next? Here is a version that deals with stdin: stackoverflow.com/questions/12768907/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.