Jordan Atkinson
Jordan Atkinson

Reputation: 202

Appending 0's to a file in unix/bash if the line is less than a fixed length

I am looking for a way in which to append 0's to the end of multiple lines in a file if they are less than 66 characters in length so that the total line length equals 66.

Here's an example of the file format (... denotes preceding 56 characters):

$cat file1
...1234567891
...123456
...
...12345678

Ideal format:

...1234567891
...1234560000
...0000000000
...1234567800

Upvotes: 1

Views: 1496

Answers (8)

ctac_
ctac_

Reputation: 2471

In pure bash

printf -v A '0%.s0' {1..66};while read B;do B=$B$A;printf '%.66s\n' $B;done<infile

Upvotes: 0

RavinderSingh13
RavinderSingh13

Reputation: 133458

Could you please try following awk solution too, it will not have any loop into it.

awk '{$0=sprintf("%066d",$0);match($0,/0[^(1-9)]*/);print substr($0,RLENGTH+1)substr($0,RSTART,RLENGTH)}'  Input_file

Adding a non-one liner form of solution too now.

awk '{
$0=sprintf("%066d",$0);
match($0,/0[^(1-9)]*/);
print substr($0,RLENGTH+1)substr($0,RSTART,RLENGTH)
}
'   Input_file

Let's say following is Input_file:

1234567891
123456
12345678

Then after running code output will be as follows.

123456789100000000000000000000000000000000000000000000000000000000
123456000000000000000000000000000000000000000000000000000000000000
123456780000000000000000000000000000000000000000000000000000000000

Explanation:

awk '{
$0=sprintf("%066d",$0);##Re-phrasing current line by adding necessary zeros in front of each line if its length is lesser than 66, %066d will take care of length.
match($0,/0[^(1-9)]*/);##using match for matching regex where it will match from first zero to till a non-zero value comes, so basically it collects all added 0s.
print substr($0,RLENGTH+1)substr($0,RSTART,RLENGTH)##Now printing the substring of 1st from starting of RLENGTH and another substring which will print from RSTART to RLENGTH, now important thing here is what are RLENGTH and RSTART, these are awk out of the box variables which will be set when a regex match is found from match where RSTART re-presents the first index number of matched regex and RLENGTH re-presents the length of matched regex.
}
' Input_file ## Mentioning the Input_file name here.

Upvotes: 1

Sundeep
Sundeep

Reputation: 23667

with perl

$ # change 13 to whatever length is needed
$ perl -lne 'print $_ . "0" x (13-length)' ip.txt 
...1234567891
...1234560000
...0000000000
...1234567800
  • $_ contains current line contents without newline character (because of -l option)
  • . will concatenate the two strings
  • x is repetition operator, here it will add as many 0s needed to make line length equal to 13 (lines greater than 13 won't be affected)
  • For inplace editing, use perl -i -lne

Upvotes: 0

Marc Lambrichs
Marc Lambrichs

Reputation: 2882

GNU awk solution:

$ awk '{s=$0; while(length(s)<66) s=s "0"; print s}' file1

or even shorter:

$ awk '{while(length<66) $0=$0 "0"}1' file1

with provided input:

$ awk '{while(length<66) $0=$0 "0"}1' file1
...123456789100000000000000000000000000000000000000000000000000000
...123456000000000000000000000000000000000000000000000000000000000
...000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000
...123456780000000000000000000000000000000000000000000000000000000

Upvotes: 3

RomanPerekhrest
RomanPerekhrest

Reputation: 92854

Awk solution:

Sample file input.txt:

ghWuec]UGaEjxQRN4qUe3uyhNmBszZeJq]0A5hZJiI[fQ[8anRKnpoLXWBwfFt300S
0jmyMPlQbSpFf[ZNdQvR]BwuYxgW6zkBYRPC1PwJEowd7[MmeiWp8Pienu1F32
G]nGbsTdvO24e7Ts5cLRIaYy[zOcUHau5Q7slRYmkcx2LTNR46QE]gs7vKPj
Zxr6HwG15YyYZnDvRDibjOKOlpacrU5oZTWhBixY23]yWfbHe4i6ztME

The job:

awk '{ if(length<66) printf "%s%0*d\n",$0,66-length,0; else print }' input.txt

The output:

ghWuec]UGaEjxQRN4qUe3uyhNmBszZeJq]0A5hZJiI[fQ[8anRKnpoLXWBwfFt300S
0jmyMPlQbSpFf[ZNdQvR]BwuYxgW6zkBYRPC1PwJEowd7[MmeiWp8Pienu1F320000
G]nGbsTdvO24e7Ts5cLRIaYy[zOcUHau5Q7slRYmkcx2LTNR46QE]gs7vKPj000000
Zxr6HwG15YyYZnDvRDibjOKOlpacrU5oZTWhBixY23]yWfbHe4i6ztME0000000000

The same could be shortened to:

awk 'length<66{ printf "%s%0*d\n",$0,66-length,0;next }1' input.txt

Upvotes: 5

Hugo G
Hugo G

Reputation: 16494

Here's a Python one-liner.

Test data

$ cat test
12345678aaaaaaaaaaaaaaaaaaaaaaa
123

33333333

Python 3

$ python3 -c 'for l in open("test"):print(l.rstrip().ljust(66,"0"))'
12345678aaaaaaaaaaaaaaaaaaaaaaa00000000000000000000000000000000000
123000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000
333333330000000000000000000000000000000000000000000000000000000000

Python 2

$ python -c 'for l in open("test"):print l.rstrip().ljust(66,"0")'
12345678aaaaaaaaaaaaaaaaaaaaaaa00000000000000000000000000000000000
123000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000
333333330000000000000000000000000000000000000000000000000000000000

In order to change the actual file, direct the output to a temporary file and override the original in the end:

$ python ... > newfile && mv newfile test

Upvotes: 2

Rahul Verma
Rahul Verma

Reputation: 3089

awk '{printf $0; for(i=66; i>length; i--){printf "0"} printf "\n"}' file

Input:

1234567891
123456
123
12345678

Output:

123456789100000000000000000000000000000000000000000000000000000000
123456000000000000000000000000000000000000000000000000000000000000
123000000000000000000000000000000000000000000000000000000000000000
123456780000000000000000000000000000000000000000000000000000000000

Upvotes: 1

Misho Tek
Misho Tek

Reputation: 644

Pseudo code:

read line by line
    while (line.length < characterNum + prefixLength)
        line += '0';
    add the line to dynamic array
make a new file with the same name (it will replace the previous one)
write data from array to the new file

characterNum is the number of needed characters, in your case 66, prefixLength is 3 in your case("...")

Instead of using dynamic array you can write lines to a new file (with a different name) right after while loop, this will save space.

Upvotes: 2

Related Questions