Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

Using Bash printf , I don't know how to understand the syntax of following code .

echo $(printf "%0.s../"  2  ); 
# ../
echo $(printf "%0.s../"  );   
# ../
echo $(printf "%0.s../" 1 );
# ../

reading from man printf,

Bytes from the string argument are printed until the end is reached or until the number of bytes indicated by the precision specification is reached; however if the precision is 0 or missing, the string is printed entirely.

and I still don't know the code above.

and why the following code prints repeatedly?

# repeating character 
echo $(printf "%0.s../" 1 2  );
# ../../

seeing from the https://wiki.bash-hackers.org/commands/builtin/printf

. The dot: Together with a field width, the field is not expanded when the text is longer, the text is truncated instead. "%.s" is an undocumented equivalent for "%.0s", which will force a field width of zero, effectively hiding the field from output

not got it yet. I need some explanation .

when the width is 0, then the field is not printed at all.

Then, if there are more arguments than fields, printf repeats the format

printf '%.7s../\n' ABCDEFG abcdefg
ABCDEFG../
abcdefg../

What you have is classic problem of having fewer format specifiers than the actual arguments for the case of

printf "%0.s../" 1 2

Bash applies the specifier rules one-on-one with the arguments, but in a case of incorrect match, the specifier rules are basically copied as if its running as

printf "%0.s../../" 1

You need to add an extra specifier for 2 as

printf "%0.s..%0.s/" 1 2

in which case you just get a single ../ output as the formatting rules match.

As for the syntax %0.s, it seems to be truncating the argument string provided as you've noted. The only problem with your logic is the incorrect specifiers as explained above. The width field makes more sense when printing long values in the shell in which the precision with is controlled by the width fields. E.g.

printf '%4.2f\n' 1323.343233
1323.34

which printf() understands as you have a number that comprise of 4 digits preceding the dot and a precision digits of maximum 2.

You don't need to echo the output of printf() in the first-place. You can use the format specifier \n at the end to print the newline.

printf "%0.s..%0.s/\n" 1 2
                Shell doesn't mean precision field gets superseded : case in point, in my zsh———————-----------— printf '%20.3f\n' 1323.343233——————— ——————————— --------------------------------  ____________1323.343---------------------- (i padded the underscores to prevent format truncation here - those are actually just spaces)
– RARE Kpop Manifesto
                Jun 7, 2022 at 12:01
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.