Convert Text to Table (Space Delimited or Fixed length)

╄→尐↘猪︶ㄣ 提交于 2020-01-23 04:10:32

问题


I have a text file with tab delimited data (150 lines) that i want to convert to space delimited or fixed length columns. I have tried to export the file using Excel's .prn format but when opened in MS Notepad it loses all formatting.

Let us consider the file as:

Product Name    Product Key
Autodesk 3ds Max 2019   128K1
Autodesk 3ds Max 2019 with Softimage    978K1
Autodesk Advance Steel 2019 959K1
Autodesk Alias AutoStudio 2019  966K1
Autodesk Alias Concept 2019 A63K1
Autodesk Alias Design 2019  712K1
Autodesk Alias SpeedForm 2019   A62K1
Autodesk Alias Surface 2019 736K1
Autodesk AutoCAD 2019   001K1

Now what is want is this:

       Product Name                  Product Key
Autodesk 3ds Max 2019                   128K1
Autodesk 3ds Max 2019 with Softimage    978K1
Autodesk Advance Steel 2019             959K1
Autodesk Alias AutoStudio 2019          966K1
Autodesk Alias Concept 2019             A63K1
Autodesk Alias Design 2019              712K1
Autodesk Alias SpeedForm 2019           A62K1
Autodesk Alias Surface 2019             736K1
Autodesk AutoCAD 2019                   001K1

I have used this tool and it does the job but again when saving in MS Notepad, the columns are misalinged and i want the data only in Notepad...

P.S. Is there anyway to do it using any tool that works in Notepad..EXCEL.CMD.SHELL. I love terminal.💔

Thanks in Advance...!


回答1:


Could you please try following.

awk '
FNR==NR{
  len=length($0)>len?length($0):len
  next
}
{
  val=$NF
  $NF=""
  $1=$1
  printf("%-"len"s%s\n",$0,val)
}
'  Input_file  Input_file

One liner form of solution:

awk 'FNR==NR{len=length($0)>len?length($0):len;next}  {val=$NF;$NF="";$1=$1;printf("%-"len"s%s\n",$0,val)}'  Input_file  Input_file

Explanation: Adding explanation of above code.

awk '                                       ##Starting awk program from here.
FNR==NR{                                    ##Checking condition FNR==NR which will be TRUE when first time Input_file is being read.
  len=length($0)>len?length($0):len         ##Creating variable len whose value is either length of current line or len value whichever is having higher value.
  next                                      ##next will skip all further statements from here.
}                                           ##Closing BLOCK for FNR==NR condition here.
{                                           ##Starting BLOCK which will be executed when 2nd time Input_file is being read.
  val=$NF                                   ##Creating variable val whose value is $NF(last field of current line).
  $NF=""                                    ##Nullifying last field of current line.
  $1=$1                                     ##re-assigning value of $1 to itself to adjust $0.
  printf("%-"len"s %s\n",$0,val)            ##Printing current line with mentioning %- with variable len to add spaces at last of current line and then printing last field with new line.
}                                           ##Closing BLOCK for which was opened for 2nd time Input_file is being read.
'  Input_file  Input_file                   ##Mentioning Input_file names here.

Output will be as follows.

Product Name Product                         Key
Autodesk 3ds Max 2019                        128K1
Autodesk 3ds Max 2019 with Softimage         978K1
Autodesk Advance Steel 2019                  959K1
Autodesk Alias AutoStudio 2019               966K1
Autodesk Alias Concept 2019                  A63K1
Autodesk Alias Design 2019                   712K1
Autodesk Alias SpeedForm 2019                A62K1
Autodesk Alias Surface 2019                  736K1
Autodesk AutoCAD 2019                        001K1

For Windows Users:

If you have installed Windows Subsystem for Linux, you can directly execute the awk script as described above on the bash command line.
If you have installed (or going to install) gawk as an independent application software, following guidance will help:

  • First download Gawk for Windows from an appropriate server such as sourceforge. There are two types of installation: with installer or without installer. The choice is up to you. Following description is based on the case without installer.

  • Unzip the downloaded file to extract binaries and modules in an arbitrary location. (Download folder, desktop, or wherever).

  • Create a working folder with an arbitrary name (such as "myawk") on your desktop or wherever convenient.

  • Copy the script below to a file with an arbitrary name (such as "script.txt").
    As awk executable doesn't care about the extension of the script file, you can keep it with ".txt" to associate a text editor or can change to ".awk" for specification.

    FNR==NR{
      len=length($0)>len?length($0):len
      next
    }
    {
      val=$NF
      $NF=""
      $1=$1
      printf("%-"len"s%s\n",$0,val)
    }
    
  • Open a cmd terminal and chdir to the working folder created above.

  • Then type on the terminal as follows:

    C:\your\path\to\gawk.exe -f script.txt Input_file.txt Input_file.txt > Output_file.txt
    

    Please modify the string "C:\yout\path\to\gawk.exe" according to your system.
    If you have installed gawk with installer or have appended the-path-to-gawk-executable to the environment variable PATH, you can just type as:

    gawk.exe -f script.txt Input_file.txt Input_file.txt > Output_file.txt
    
  • You can find the result in Output_file.txt. Please make sure you are using monospace font to display the columns aligned vertically.

Although it has passed a long time since awk or gawk was born, it is still not outdated. Please enjoy hacking awk to increase job efficiency and productivity.




回答2:


perl version (Since it sounds like you're using Windows, install Strawberry Perl if you don't have perl already):

#!/usr/bin/env perl
# Save in a file instead of trying to use as a one-liner
use warnings;
use strict;
use autodie;
use List::Util qw/max/;
use Fcntl qw/:seek/;

my $file = shift;
open my $INFILE, "<", $file;

my @lens;
while (<$INFILE>) {
  chomp;
  my @F = split /\t/;
  for my $col (0 .. $#F) {
    $lens[$col] = max(length $F[$col], $lens[$col]//0);
  }
}

seek $INFILE, 0, SEEK_SET;

while (<$INFILE>) {
  chomp;
  my @F = split /\t/;
  for my $col (0 .. $#F) {
    printf "%-*s ", $lens[$col], $F[$col];
  }
  print "\n";
}

Example:

$ perl widify input.tsv
 Product Name                         Product Key 
 Autodesk 3ds Max 2019                128K1       
 Autodesk 3ds Max 2019 with Softimage 978K1       
 Autodesk Advance Steel 2019          959K1       
 Autodesk Alias AutoStudio 2019       966K1       
 Autodesk Alias Concept 2019          A63K1       
 Autodesk Alias Design 2019           712K1       
 Autodesk Alias SpeedForm 2019        A62K1       
 Autodesk Alias Surface 2019          736K1       
 Autodesk AutoCAD 2019                001K1



回答3:


This might work for you (GNU sed):

sed -E '1{s/\S+ \S+/       &              /;b};:a;/^.{39,} \S+$/!s/^(.*) /\1  /;ta' file

The headings are placed above the columns, and the remaining lines have the first field padded on the right by spaces so that it is set to a width of 40 characters.




回答4:


PowerShell is available for UNIX/Linux systems, Mac, and Windows. https://github.com/PowerShell/PowerShell

PS 13:38  C:\src\t
C:>type ./tsv2fixed.ps1
Import-Csv -Path 'tsv2fixed.txt' -Delimiter "`t" |
    ForEach-Object {
        "{0,-40}{1}" -f @($_.'Product Name', $_.'Product Key')
    } |
    Out-File -FilePath './tsv2fixed-out.txt' -Encoding ascii
PS 13:38  C:\src\t
C:>./tsv2fixed.ps1
PS 13:38  C:\src\t
C:>type ./tsv2fixed-out.txt
Autodesk 3ds Max 2019                   128K1
Autodesk 3ds Max 2019 with Softimage    978K1
Autodesk Advance Steel 2019             959K1
Autodesk Alias AutoStudio 2019          966K1
Autodesk Alias Concept 2019             A63K1
Autodesk Alias Design 2019              712K1
Autodesk Alias SpeedForm 2019           A62K1
Autodesk Alias Surface 2019             736K1
Autodesk AutoCAD 2019                   001K1


来源:https://stackoverflow.com/questions/59015387/convert-text-to-table-space-delimited-or-fixed-length

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!