3

I want to format my text file for better appearance. So I want any command or any shell script which will format my file as per my expectation. Input File:

Index Name City
1. Ravi Bhuva Ahmedabad
2. Gaurav Bhuva Rajkot
3. Nimesh Godhasara Junagadh
4. Abhyuday Godhasara Nadiyad
.
.
100. abcd xyz

Output File:

Index  Name                          City
1.     Ravi Bhuva                    Ahmedabad
2.     Gaurav Bhuva                  Rajkot
3.     Nimesh Godhasara              Junagadh
4.     Abhyuday Godhasara            Nadiyad
.
.
100.   abcd                          xyz
9
  • Are you open to using Microsoft Excel to achieve this?
    – Garrulinae
    May 2, 2014 at 5:11
  • No it's simple new.txt file. May 2, 2014 at 5:31
  • But do you have Excel available? Excel can modify text files. I have submitted an answer below that will work.
    – Garrulinae
    May 2, 2014 at 5:39
  • 1
    Is the format even deterministically parseable? If the Name column contains space, it has to be separated from the City with something else, otherwise no tool would be able to process it reliably.
    – Jan Hudec
    May 2, 2014 at 10:14
  • 3
    @ravibhuva9955: Then you really need to have a look at whatever produces the file. Both city names and names of people can contain extra words and if there is no better separator (at least a tab), there is no way to separate them without knowing the cities.
    – Jan Hudec
    May 2, 2014 at 11:55

3 Answers 3

2

perl.

Assumption: the city only has a single word.

perl -MList::Util=max -lane '
    push @num,  shift @F; 
    push @city, pop @F; 
    push @name, join(" ", @F); 
    END {
        @max = (
            max(map {length} @num),
            max(map {length} @name),
            max(map {length} @city)
        );
        printf "%-*s  %-*s  %-*s\n", 
            $max[0], $num[$_], 
            $max[1], $name[$_], 
            $max[2], $city[$_]
        for (0..$#num);
    }
' <<END
Index Name City
1. Ravi Bhuva Ahmedabad
2. Gaurav Bhuva Rajkot
3. Nimesh Godhasara Junagadh
4. Abhyuday Godhasara Nadiyad
42. a b c d e f city
100. abcd xyz
END

output

Index  Name                City     
1.     Ravi Bhuva          Ahmedabad
2.     Gaurav Bhuva        Rajkot   
3.     Nimesh Godhasara    Junagadh 
4.     Abhyuday Godhasara  Nadiyad  
42.    a b c d e f         city     
100.   abcd                xyz      
4

You need something to delimit names from cities (since cities may also have more than one word, presumably). Are all names exactly two tokens (first+last)? If so, you can assume anything after the the index and two-part name is city name. Here's one that does so:

cat new.txt | sed 's/^\(\S\+\)\s/\1~/' | sed 's/^\(\S\+\s\+\S\+\)\s\+\(.*\)$/\1~\2/' | column -s \~ -t

though the last label at the top (city) must be aligned manually.

1
  • +1 for the idea, but the execution is not quite right: sed -r 's/\s+/~/; s/\s+(\S+)$/~\1/' new.txt | column -s \~ -t -- with this, the headings are aligned automatically. May 7, 2014 at 17:41
2

Most Linux systems have python running on them. Running this python script will get you the results you're looking for:

line_template = "{:8}\t{:20}\t{}\n"
name_template = "{} {}"

with open('test.txt') as f:
    with open('test_new.txt', 'w') as f_new:
        first_line = f.readline()
        ind, name, city = first_line.split()
        f_new.write(line_template.format(ind, name, city))

        for line in f:
            ind, first_name, last_name, city = line.split()
            name_string = name_template.format(first_name, last_name)
            f_new.write(line_template.format(ind, name_string, city))

I used you're original first 4 entries above and produced the following output file:

Index       Name                    City
1.          Ravi Bhuva              Ahmedabad
2.          Gaurav Bhuva            Rajkot
3.          Nimesh Godhasara        Junagadh
4.          Abhyuday Godhasara      Nadiyad

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .