I would like using AWK (Windows) to convert a text file with a single column to multiple columns - count specified in script or on command line.
This question has been asked before but my final data file needs to have the same column count all the way.
Example of input:
L1
L2
L3
L4
L5
L6
L7
split into 3 columns and ";" as separator
L1;L2;L3
L4;L5;L6
L7;; <<< here two empty fields are created after end of file, since I used just one on this line.
I tried to modify variants of the typical solution given: NR%4 {printf $0",";next} 1;
and a counter, but could not quite get it right.
I would prefer not to count lines before, thereby running over the file multiple times.
CodePudding user response:
You may use this awk
solution:
awk -v n=3 '{
sub(/\r$/, "") # removes DOS line break, if present
printf "%s", $0(NR%n ? ";" : ORS)
}
END {
# now we need to add empty columns in last record
if (NR % n) {
for (i=1; i < (n - (NR % n)); i)
printf ";"
print ""
}
}' file
L1;L2;L3
L4;L5;L6
L7;;
CodePudding user response:
With your shown samples please try following awk
code. Using xargs
awk
combination to achieve the outcome needed by OP.
xargs -n3 < Input_file |
awk -v OFS=";" '{if(NF==1){$0=$0";;"};if(NF==2){$0=$0";"};$1=$1} 1'
CodePudding user response:
Using any awk:
$ awk -v n=3 -v OFS=';' '
{ rec=rec sep $0; sep=OFS }
!(NR%n) { print rec; rec=sep="" }
END { if (NR%n) { $0=rec; NF=n; print } }
' file
L1;L2;L3
L4;L5;L6
L7;;
That above uses Unix quoting, you'd have to figure out the Windows equivalent for yourself or store the script in a file.
CodePudding user response:
paste
is designed to do this:
paste -d';' - - - <file
For an awk
I would do:
awk -v row=3 '
{printf("%s%s", $0, (NR%row>0) ? ";" : ORS)}
END{
for(i=NR%row; i<row-1; i ) printf(";")
printf ORS
}' file
Or you can use ruby
:
ruby -e '
row=3
puts $<.read.
split(/\r?\n/).
each_slice(row).
map{|sl| sl.fill(sl.size...row) { "" }; sl.join(";") }.
join("\n") # "\r\n" for Windows
' file
Any of those prints:
L1;L2;L3
L4;L5;L6
L7;;