Warm tip: This article is reproduced from serverfault.com, please click

How to write a shell script to swap columns in txt file?

发布于 2020-11-28 13:14:25

I was trying to solve one of my old assignment I am literally stuck in this one Can anyone help me?

There is a file called "datafile". This file has names of some friends and their

ages. But unfortunately, the names are not in the correct format. They should be

lastname, firstname

But, by mistake they are firstname,lastname

The task of the problem is writing a shell script called fix_datafile

to correct the problem, and sort the names alphabetically. The corrected filename

is called datafile.fix .

Please make sure the original structure of the file should be kept untouched.

The following is the sample of datafile.fix file:

#personal information

#******** Name ********* ***** age *****

Alexanderovich,Franklin 47

Amber,Christine 54

Applesum,Franky 33

Attaboal,Arman 18

Balad,George 38

Balad,Sam 19

Balsamic,Shery 22

Bojack,Steven 33

Chantell,Alex 60

Doyle,Jefry 45

Farland,Pamela 40

Handerman,jimmy 23

Kashman,Jenifer 25

Kasting,Ellen 33

Lorux,Allen 29

Mathis,Johny 26

Maxter,Jefry 31

Newton,Gerisha 40

Osama,Franklin 33

Osana,Gabriel 61

Oxnard,George 20

Palomar,Frank 24

Plomer,Susan 29

Poolank,John 31

Rochester,Benjami 40

Stanock,Verona 38

Tenesik,Gabriel 29

Whelsh,Elsa 21

Questioner
kjbjjknjkbasjx
Viewed
0
Taras Khalymon 2020-11-28 22:04:01

If you can use awk (I suppose you can), than this there's a script which does what you need:

#!/bin/bash
RESULT_FILE_NAME="datafile.new"
cat datafile.fix | head -4 > datafile.new
cat datafile.fix | tail -n +5 | awk -F"[, ]" '{if(!$2){print()}else{print($2","$1, $3)}}' >> datafile.new

Passing -F"[, ]" allows awk to split columns both by , and space and all that remains is just print columns in a needed format. The downsides are that we should use if statement to preserve empty lines and file header also should be treated separately.

Another option is using sed:

cat datafile.fix | sed -E 's/([a-zA-Z]+),([a-zA-Z]+) ([0-9]+)/\2,\1 \3/g' > datafile.new

The downside is that it requires regex that is not as obvious as awk syntax.