While printf
is a print formatted function, print
concatenates parameters.
Looks like you need to check out the printf
function (or both).
In short it is:
printf <format, <parameter1>[, <parameter2>, ...] | text>
The letter %
in a format denotes here comes a parameter that should be formatted as .... Format can hold special sequences like \t
, \n
. Printf does not terminate output by newline. If only one argument is given it is normally printed as is.
If it is a number the default formatting is "%.6g
":
CODE : printf 1.123456789
RESULT: 1.12346
If e.g. $1
is 1.123456789
it is normally treated as text, as in:
CODE : printf $1
RESULT: 1.123456789
CODE : printf $1+0 # Force conversion to number
RESULT: 1.12346
When you give more then one argument the first one is used as format and the rest as parameters. If to few parameters are given to fulfill the pattern the behavior is undefined.
printf "%d %s\n", 123, "hello"
|| | | | |
|| | | | +----- Parameter 2
|| | | +------------ Parameter 1
|| | +----------------- Print new-line
|| +------------------- Print parameter 2 as string
|+--------------------- Print literal space
+---------------------- Print parameter 1 as digit
printf "%d %s\n", 123, "hello"
# Gives: 123 hello
printf "%d %s\n", "hello", 123
# Gives: 0 123
printf "%d %s\n", 123
# Gives undefined result (according to format one parameter is missing)
And if arguments are given without any placeholder the are discarded:
printf "%d", 123
# Gives: 123
printf "%d", 123, 22
# Gives: 123
printf "%d", 123, 22, "\t", "foo", 5566, 12.55, "\n", "blah"
# Gives: 123
The %
character denotes "here is a conversion specification". If a non valid specification is given, as in one that is not defined by awk
, the behavior is unspecified. Other text is treated as normal text.
printf "Hello %w", "what"
# Usually: Hello %w
# But no guarantee
printf "ABC", "DEF", "GHI"
# Result: ABC
In your code you frequently use input from file as format for printf. If those fields are not printf
formats they are printed as normal text. Parameters are discarded.
# Example, say:
# $4 = "%d %s\n"
# $8 = "33.2"
# $9 = "good"
printf $4, $8, $9
#
# Result: 33 good
# Say:
# $4 = "14"
# $8 = "33.2"
# $9 = "good"
printf $4, $8, $9
#
# Result: 14
printf $4, "\t", $8, "\t", $9
#
# Result: 14
Your script formatted:
< pool.sam awk '
# 1.
/./ { # IF line not empty THEN
printf $1 # print field 1
} # ENDIF
# 2.
{
printf $7 + 1, "\t" # printf with format = $7 + 1 and parameter <tab>
}
# 3.
{
printf $3, "\t" # printf with format = $3 and parameter <tab>
}
# 4.
{
# 4.1
if ($2 != 16) { # IF field 2 is not 16 THEN
print "\t", "+"; # print <tab> + "+" (Terminate with newline)
} else { # ELSE
print "\t", "-"; # print <tab> + "-" (Terminate with newline)
} # ENDIF
# 4.2
{
printf $4, "\t", length($10) + $4, "\t", "1"
# printf: pattern="field 4"
# parameters=<tab>, length of field 10 + field 4
}
}
'
Say you have:
$ cat pool.sam
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
That would give you (using numbering in code above):
1. printf "1"` => `1`
2. printf 8, "\t"` => `8`
3. printf "3", "\t" => `3`
4.1 print "\t", "+" => `<tab>+<new-line>`
4.2 printf "4", "\t", 6, "\t", "1" => `4`
Final result:
183 +
4
A rewrite that might get you somewhat on the way:
awk '
/./ {
printf "%s%d\t%d\t", $1, $7 + 1, $3
if ($2 != 16) {
printf "+"
} else {
printf "-"
}
printf "%d\t%d\t1\n", $4, length($10) + $4
}
' pool.sam
The if statement, (in danger of confusing you), can also be written in one go as:
printf "%s", $2 != 16 ? "+" : "-"
Read up on format strings and printf
. The align format is often very useful, as is formatting of floats etc.
right_pad=-10
printf "%*s: %5d\n", right_pad, "vix", 23
printf "%*s: %5d\n", right_pad, "popul", 336
printf "%*s: %5.2f\n", right_pad, "vidi", 42.129542488
printf "%5s %-10d +%d\n", "OK", 33, 44
Output:
vix : 23
popul : 336
vidi : 42.13
OK 33 +44
Easiest, at least I find it, is to use a script instead of command-line when playing around.
pool.sam
and an example of the output you are after...value1 value2 value3 value7
are only four (4) values. your script references up to ten values ($10
)