Jak sformatować plik tekstowy, aby uzyskać lepszy wygląd?

3

Chcę sformatować plik tekstowy, aby uzyskać lepszy wygląd. Chcę więc dowolnego polecenia lub dowolnego skryptu powłoki, który sformatuje mój plik zgodnie z moimi oczekiwaniami. Plik wejściowy:

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

Plik wyjściowy:

Index  Name                          City
1.     Ravi Bhuva                    Ahmedabad
2.     Gaurav Bhuva                  Rajkot
3.     Nimesh Godhasara              Junagadh
4.     Abhyuday Godhasara            Nadiyad
.
.
100.   abcd                          xyz
ravibhuva9955
źródło
Czy jesteś otwarty na używanie Microsoft Excel, aby to osiągnąć?
Garrulinae
Nie, to prosty plik new.txt.
ravibhuva9955
Ale czy masz dostępny program Excel? Excel może modyfikować pliki tekstowe. Podałem poniżej odpowiedź, która zadziała.
Garrulinae
1
Czy format jest nawet deterministycznie analizowalny? Jeśli Namekolumna zawiera przestrzeń, należy ją oddzielić od Cityczegoś innego, w przeciwnym razie żadne narzędzie nie byłoby w stanie przetwarzać jej w niezawodny sposób.
Jan Hudec
3
@ ravibhuva9955: Zatem naprawdę musisz rzucić okiem na to, co produkuje plik. Zarówno nazwy miast, jak i nazwiska osób mogą zawierać dodatkowe słowa, a jeśli nie ma lepszego separatora (przynajmniej karty), nie ma możliwości ich rozdzielenia bez znajomości miast.
Jan Hudec

Odpowiedzi:

2

perl.

Założenie: miasto ma tylko jedno słowo.

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

wynik

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      
Glenn Jackman
źródło
4

Potrzebujesz czegoś, aby oddzielić nazwy od miast (prawdopodobnie miasta mogą zawierać więcej niż jedno słowo). Czy wszystkie imiona są dokładnie dwoma tokenami (pierwszy + ostatni)? Jeśli tak, możesz założyć cokolwiek po indeksie, a dwuczęściowa nazwa to nazwa miasta. Oto taki, który to robi:

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

chociaż ostatnia etykieta u góry (miasto) musi zostać wyrównana ręcznie.

1337 we wtorki
źródło
+1 za pomysł, ale wykonanie nie jest w porządku: sed -r 's/\s+/~/; s/\s+(\S+)$/~\1/' new.txt | column -s \~ -t- dzięki temu nagłówki są automatycznie wyrównane.
glenn jackman
2

W większości systemów Linux działa na nich Python. Uruchomienie tego skryptu Python zapewni wyniki, których szukasz:

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))

Użyłem twoich oryginalnych pierwszych 4 wpisów powyżej i stworzyłem następujący plik wyjściowy:

Index       Name                    City
1.          Ravi Bhuva              Ahmedabad
2.          Gaurav Bhuva            Rajkot
3.          Nimesh Godhasara        Junagadh
4.          Abhyuday Godhasara      Nadiyad
James Mertz
źródło