Bash detecting number of digits in line

Hi I have a problem, I am attempting to write a bash script that goes through a file and can determine how many characters are at a set point in a line starting with QTY+113:100:PCE, If it detects 3 digits (number in bold) then pad it out with 12 zero's

If there are only two digits then pad it out with 13 zero's, also removing the + and : and adding the correct spacing if possible.

These numbers change, hence why I need it to detect how many characters

QTY+113:100:PCE

I need it to return

QTY   113000000000000100PCE

and if there are two numbers like

QTY+113:50:PCE

I need it to return

QTY   113000000000000050PCE

Any help would be greatly appreciated.

Hello firefox2k2,

Could you please try following and let me know if this helps.

 echo "QTY+113:100:PCE" | awk -F":" '{if(length($2)==3||length($2)==2){sub(/\+/,X,$1);printf "%s%015d%s\n", $1, $2, $3}}'
 

Output will be as follows.

 QTY113000000000000100PCE
 

For input with 2 digits as per your input it will be as follows.

 echo "QTY+113:50:PCE" | awk -F":" '{if(length($2)==3||length($2)==2){sub(/\+/,X,$1);printf "%s%015d%s\n", $1, $2, $3}}'
 

Output will be as follows.

 QTY113000000000000050PCE
 

Thanks,
R. Singh

Hi that works great, how do I include this line in the small script below so it makes the changes?

I am very new to this

for file in *.TEST
do
sed -i 's/DTM+/DTM07 /' $file
done

Thank you for the help

Hello,

You haven't showed us the input file in first post of this thread, I have answered according to your question. Nevertheless you can try following. If following doesn't help you then kindly provide details as follows:

I- Your O.S name please.
II- Your input file how it looks an example with few data sample.
III- If above solutions are not working then show us errors which you are getting please.

Following code you can use may be helpful for you, also to appreciate anyone in this forum you can always push THANKS button present in below of any thread please.

 awk -F":" '{if(length($2)==3||length($2)==2){sub(/\+/,X,$1);printf "%s%015d%s\n", $1, $2, $3}}' chumma.txt
 

You can give one file as for above code for testing purposes, if All is Well with above code then you can give as you are giving in your sample code shown.

Thanks,
R. Singh

1 Like

How is the important number generated? If it is in a shell script, you can use typeset -Z15 variable to automatically pad it, if that helps.

Can you tell us more about the overall process? There may be a better solution.

Robin

1 Like

Hi Robin, below is an example of the original text file I am starting with, the numbers are an order quantity, they can be anything from 0 to 100's:

DTM+64:20160601:102'
DTM+63:20160630:102'
QTY+113:50:PCE'
SCC+4'
DTM+64:20160701:102'
DTM+63:20160731:102'
QTY+113:50:PCE'
SCC+4'
DTM+64:20160801:102'
DTM+63:20160831:102'
QTY+113:0:PCE'
SCC+4'
DTM+64:20160901:102'
DTM+63:20160930:102'
QTY+113:50:PCE'
SCC+4'
DTM+64:20161001:102'
DTM+63:20161031:102'
QTY+113:0:PCE'
SCC+4'
DTM+64:20161101:102'
DTM+63:20161130:102'

I need it to look like this :

DTM07 64 20160601                           102
DTM07 63 20160630                           102
QTY   113000000000000050PCE4  
DTM07 64 20160701                           102
DTM07 63 20160731                           102
QTY   113000000000000050PCE4  
DTM07 64 20160801                           102
DTM07 63 20160831                           102
QTY   113000000000000000PCE4  
DTM07 64 20160901                           102
DTM07 63 20160930                           102
QTY   113000000000000050PCE4  
DTM07 64 20161001                           102
DTM07 63 20161031                           102
QTY   113000000000000000PCE4  
DTM07 64 20161101                           102
DTM07 63 20161130                           102

I can do a lot of it with sed and its easier because you can edit files in place with sed, not used awk much so a little lost

Thank you again for taking the time to help.

So can I just clarify the rules:-

  • You only want DTM & QTY records
  • Input is delimited by + or :
  • Trailing ' is ignored
  • DTM records are output as DTM07 with space separated fields of length 5, 2, 8, 29 (right justified)
  • QTY records are output with fields of length 6 (left justified), 3, 15 (zero padded), 5 (left justified)

How would you like to have the code written? What are you most comfortable in? Options include awk, sed, perl, ksh script, C, others?

Think about what you would like to support in the future.

Sorry for so many questions,
Robin

Hello firefox2k2,

Following may help you in same, let me know if you have any queries.

 awk -F":" -vs1="'" '{sub(/\+/," ",$1);sub(/DTM/,"DTM07",$1);sub(s1,X,$NF);if(length($NF)==2 || length($NF)==3 && $1 ~ /DTM07/){printf "%s %d %15d\n", $1, $2, $3}};{if($1 ~ /QTY/){sub(/\+/,":",$1);printf "%s%015s%s\n", $1, $2, $3}}' Input_file
 

Output will be as follows.

DTM07 64 20160601             102
DTM07 63 20160630             102
QTY 113000000000000050PCE
DTM07 64 20160701             102
DTM07 63 20160731             102
QTY 113000000000000050PCE
DTM07 64 20160801             102
DTM07 63 20160831             102
QTY 113000000000000000PCE
DTM07 64 20160901             102
DTM07 63 20160930             102
QTY 113000000000000050PCE
DTM07 64 20161001             102
DTM07 63 20161031             102
QTY 113000000000000000PCE
DTM07 64 20161101             102
DTM07 63 20161130             102
 

EDIT: Adding a non one-liner form for same.

 awk -F":" -vs1="'" '{
                        sub(/\+/," ",$1);
                        sub(/DTM/,"DTM07",$1);
                        sub(s1,X,$NF);
                        if(length($NF)==2 || length($NF)==3 && $1 ~ /DTM07/)
                    {
                        printf "%s %d %15d\n", $1, $2, $3
                    }
                    };
                    {
                        if($1 ~ /QTY/)
                    {
                        sub(/\+/,":",$1);
                        printf "%s%015s%s\n", $1, $2, $3
                    }
                    }
                   ' Input_file
 

Thanks,
R. Singh

Try also

awk -F: -vsq="\'" '

/^QTY/          {sub (/\+/, "   ")
                 getline X
                 $0 = $0 X
                 sub ("SCC\+", "")
                 OFS=""
                 $2 = sprintf ("%015d", $2)
                 OFS=" "
                }

/^DTM/          {sub (/\+/, "07 ", $1)
                 $NF = sprintf ("%28s%s", " ", $NF)
                }

                {gsub (sq, _)}
 
1
' file
DTM07 64 20160601                             102
DTM07 63 20160630                             102
QTY   113000000000000050PCE4
DTM07 64 20160701                             102
DTM07 63 20160731                             102
QTY   113000000000000050PCE4
DTM07 64 20160801                             102
DTM07 63 20160831                             102
QTY   113000000000000000PCE4
DTM07 64 20160901                             102
DTM07 63 20160930                             102
QTY   113000000000000050PCE4
DTM07 64 20161001                             102
DTM07 63 20161031                             102
QTY   113000000000000000PCE4
DTM07 64 20161101                             102
DTM07 63 20161130                             102