4

I want to put leading 0 characters to some input, resulting in a fixed length (length given by a variable). The input can be a number or a string.
I want to catch the output in a variable.

I tried this:

awk '{j=$(printf "%04d\n"); echo $j}'  

but it is throwing this error:

awk: line 1: syntax error at or near printf
3
  • 1
    awk has an sprintf function Commented Feb 23, 2018 at 17:15
  • what would be the syntax for assigning to a variable in awk for case like below awk '{j=$(printf "%04d\n"); echo $j}' Commented Feb 23, 2018 at 17:18
  • Perhaps change the title of the question into something like "How can I format a string into a fixed length with leading characters" Commented Feb 24, 2018 at 11:49

2 Answers 2

9

Use

 awk '{j=sprintf("%04d", NR); print j}' 

to put the record number in the variable j.

Sign up to request clarification or add additional context in comments.

10 Comments

awk '{j=$(sprintf "%04d\n"); echo $j}' awk: line 1: syntax error at or near %04d
You need an argument for that format string. What number are you trying to get? Also, the newline is redundant, since the print statement will add one.
I'll edit the answer to put the record number in the variable.
need to assign something like j="0000" in awk where number of zeros is not hardcoded. so i am trying to use j=$(sprintf "%04d\n") where value 4 or what ever number will be passing thru a variable
Sounds like you want j=sprintf("%04d", 0). Or, if 4 is a variable, something like: echo foo | awk '{j=sprintf("%0"n"d", 0); print j}' n=7
|
0

When you want to print the number n width total with w, you can use

n=12
w=8
printf "%0*d\n" $w $n

When you want the result in a var, you can use

printf -v j "%0*d" $w $n
echo "j=[$j]"
# Result:
j=[00000012]

It becomes more complex when you want to support strings as well. A simple patch seems to work

s="Hello"
w=8
# Wrong:
printf "%*s\n" $w "$s" | tr ' ' '0'

The problem with this solution is that it will also replace the spaces in $s. You can use a sed construction for this:

s="Hello World with Spaces"
w=40
printf "%*s\n" $w "$s"| sed -r ':a;s/^( *) /\10/;ta'
j=$(printf "%*s" $w "$s"| sed -r ':a;s/^( *) /\10/;ta')

The sedconstruction will loop over the input, replacing one space each time (the last leading space) with a 0. The \1 will put back the other leading spaces.
When it is hard to understand, look how to replace 2 spaces by 'x':

printf "%*s\n" $w "$s"| sed -r 's/^( *) /\1x/;s/^( *) /\1x/'

EDIT: The solution is not perfect. When the inputstring starts with spaces, these spaces are replaced by zeroes too, and that might not be desired behaviour: s=" I started with a space".

The solution seems to be calculating the number of zeroes first: The total width $w minus the stringlength ${#s}. When you need at least one additional 0, you can use

printf "%0*d%s\n" $(($w - ${#s})) 0 "$s"

5 Comments

If not number if alpha numeric, say n=ABC123 , need j output as [00ABC123]
Replacing strings is more difficult, especially when you consider spaces in the string. See edit for an improved command.
i see using something like printf "%*s\n" $w "$s"| sed -r 's/^( *) /\1x/;s/^( *) /\1x/' would give length 42 like ( xxHello World with Spaces) rather than expected length 40 like ( xxHello World with Spaces). But another command printf "%*s\n" $w "$s"| sed -r ':a;s/^( *) /\10/;ta' is giving length 40. Where is the difference coming?
To put it into simple way printf "%*s\n" $w "$s"| sed -r ':a;s/^( *) /\10/;ta' we are using "\10" and the back reference \1 contains spaces. Assuming there are 3 spaces before text "Hello World with Spaces" since we used "\10" the output generally is (3spaces000Hello World with Spaces). Where the initial spaces are gone. Could pls explain
printf "%*s\n" $w "$s"| sed -r 's/^( *) /\1x/;s/^( *) /\1x/' | wc retuns 41 with me (including newline character, I hope your output is not ending with \r\n). I do not understand your different line lenghts. \s\s\sHello is changed into 000Hello because there is a space after ) in s/^( *) /\10/. The back ref matches 2 spaces, the third one is replaced by a 0.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.