0

I have a file like below with two fields ending with *.alarms.gz and *.values.gz, want to allign the files like all the alarms.gz in first field and all the values.gz in second field. How can i achieve this.

Sample Input

    20190412.alarms.gz              20190415_02E9EA3400B1CF41.values.gz
    20190412.alarms.gz              20190415_02E9EA3400B1CF41.values.gz
    20190412.alarms.gz              20190415_02E9EA3400B1CF41.values.gz
    20190412.alarms.gz              20190415_02E9EA3400B1CF41.values.gz
    20190412.alarms.gz              20190415_02E9EA3400B1CF41.values.gz
    20190412_92E9EA3400B1CF41.values.gz               20190412.alarms.gz
    20190412.alarms.gz              20190415_42E9EA3400B1CF41.values.gz
    20190412.alarms.gz              20190415_32E9EA3400B1CF41.values.gz
    20190412.alarms.gz              20190412_12E1EA3400B1CFA1.values.gz

Required output

20190412.alarms.gz              20190415_02E9EA3400B1CF41.values.gz
20190412.alarms.gz              20190415_02E9EA3400B1CF41.values.gz
20190412.alarms.gz              20190415_02E9EA3400B1CF41.values.gz
20190412.alarms.gz              20190415_02E9EA3400B1CF41.values.gz
20190412.alarms.gz              20190415_02E9EA3400B1CF41.values.gz
20190412.alarms.gz              20190412_92E9EA3400B1CF41.values.gz               
20190412.alarms.gz              20190415_42E9EA3400B1CF41.values.gz
20190412.alarms.gz              20190415_32E9EA3400B1CF41.values.gz
20190412.alarms.gz              20190412_12E1EA3400B1CFA1.values.gz
2

Using awk match only those lines that are off the grid, i.e. values in $1 and alarms in $2 and swap the column values. The {..}1 re-constructs the whole line with any modifications done inside the {..} and any change to the field/record separators.

awk '$1 ~ /.*values.gz/ && $2 ~ /.*alarms.gz/ { tmp = $1; $1 = $2; $2 = tmp }1' file | 
column -t

The part column -t is just for pretty printing the output of awk. You could use the printf() with appropriate widths, but the former command makes the job easier.

But on a POSIX complaint only awk, use printf()

awk '$1 ~ /.*values.gz/ && $2 ~ /.*alarms.gz/ { tmp = $1; $1 = $2; $2 = tmp; } 
{ printf "%s%40s\n",$1,$2}' file

If you were to make the changes in-line and using GNU awk less than 4.1.2, use a temporary file for re-direct the contents out of it

tmpfile=$(mktemp)

awk '$1 ~ /.*values.gz/ && $2 ~ /.*alarms.gz/ { tmp = $1; $1 = $2; $2 = tmp }1' file | 
column -t > "$tmpfile" && mv "$tmpfile" file

or use the magical sponge tool from moreutils package ( On RHEL, do yum install moreutils)

awk '$1 ~ /.*values.gz/ && $2 ~ /.*alarms.gz/ { tmp = $1; $1 = $2; $2 = tmp }1' file | 
column -t | 
sponge file
  • 1
    Perfect, Thanks !!!. What does 1 in the last part of the 1 before single quotes means. – upkar Apr 15 at 4:51
  • 1 is used for print. awk '{print}' file is equal to awk '1' file – Kamaraj Apr 15 at 5:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.