manpagez: man pages & more
info gawk
Home | html | info | man

File: gawk.info,  Node: Printf Ordering,  Next: I18N Portability,  Prev: String Extraction,  Up: Translator i18n

13.4.2 Rearranging 'printf' Arguments
-------------------------------------

Format strings for 'printf' and 'sprintf()' (*note Printf::) present a
special problem for translation.  Consider the following:(1)

     printf(_"String `%s' has %d characters\n",
               string, length(string)))

   A possible German translation for this might be:

     "%d Zeichen lang ist die Zeichenkette `%s'\n"

   The problem should be obvious: the order of the format specifications
is different from the original!  Even though 'gettext()' can return the
translated string at runtime, it cannot change the argument order in the
call to 'printf'.

   To solve this problem, 'printf' format specifiers may have an
additional optional element, which we call a "positional specifier".
For example:

     "%2$d Zeichen lang ist die Zeichenkette `%1$s'\n"

   Here, the positional specifier consists of an integer count, which
indicates which argument to use, and a '$'.  Counts are one-based, and
the format string itself is _not_ included.  Thus, in the following
example, 'string' is the first argument and 'length(string)' is the
second:

     $ gawk 'BEGIN {
     >     string = "Don\47t Panic"
     >     printf "%2$d characters live in \"%1$s\"\n",
     >                         string, length(string)
     > }'
     -| 11 characters live in "Don't Panic"

   If present, positional specifiers come first in the format
specification, before the flags, the field width, and/or the precision.

   Positional specifiers can be used with the dynamic field width and
precision capability:

     $ gawk 'BEGIN {
     >    printf("%*.*s\n", 10, 20, "hello")
     >    printf("%3$*2$.*1$s\n", 20, 10, "hello")
     > }'
     -|      hello
     -|      hello

     NOTE: When using '*' with a positional specifier, the '*' comes
     first, then the integer position, and then the '$'.  This is
     somewhat counterintuitive.

   'gawk' does not allow you to mix regular format specifiers and those
with positional specifiers in the same string:

     $ gawk 'BEGIN { printf "%d %3$s\n", 1, 2, "hi" }'
     error-> gawk: cmd. line:1: fatal: must use `count$' on all formats or none

     NOTE: There are some pathological cases that 'gawk' may fail to
     diagnose.  In such cases, the output may not be what you expect.
     It's still a bad idea to try mixing them, even if 'gawk' doesn't
     detect it.

   Although positional specifiers can be used directly in 'awk'
programs, their primary purpose is to help in producing correct
translations of format strings into languages different from the one in
which the program is first written.

   ---------- Footnotes ----------

   (1) This example is borrowed from the GNU 'gettext' manual.

© manpagez.com 2000-2025
Individual documents may contain additional copyright information.