问题
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 Windowsfrom 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").
Asawkexecutable 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
cmdterminal andchdirto 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.txtPlease modify the string "C:\yout\path\to\gawk.exe" according to your system.
If you have installedgawkwith installer or have appended the-path-to-gawk-executable to the environment variablePATH, you can just type as:gawk.exe -f script.txt Input_file.txt Input_file.txt > Output_file.txtYou 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