< pool.sam awk '
/./ {printf $1}
{printf $7+1,"\t"}
{printf $3,"\t"}
{
if($2 !=16) {print "\t", "+";} else {print "\t","-";}
{printf $4,"\t" ,length($10)+$4, "\t", "1"}
}'
我得到了所有的值,但是以一种奇怪的方式。我正在打印 7 个值,
值1 值2 值3 值7
我想要在每一行中使用所有这 7 个值,并用 TAB 分隔。
答案1
printf
你为这项工作运行了很多s。为什么不简单地做类似的事情
cat pool.sam |\
awk '/./ {printf $1,$7+1,"\t"$3,"\t",($2!=16)?"+","-",$4,"\t",length($10)+$4,"\t1"}}'
答案2
虽然printf
是一个打印格式化函数,print
连接参数。
看起来您需要检查该printf
功能(或两者)。
简而言之就是:
printf <format, <parameter1>[, <parameter2>, ...] | text>
%
格式中的字母表示这里有一个参数,其格式应为...。格式可以保存特殊序列,例如\t
, \n
。 Printf 确实不是通过换行符终止输出。如果仅给出一个参数,则通常按原样打印。
如果是数字,则默认格式为“ %.6g
”:
CODE : printf 1.123456789
RESULT: 1.12346
如果是$1
,则1.123456789
通常将其视为文本,如下所示:
CODE : printf $1
RESULT: 1.123456789
CODE : printf $1+0 # Force conversion to number
RESULT: 1.12346
当您给出多个参数时,第一个参数用作格式,其余参数用作参数。如果给出很少的参数来满足该模式,则行为是不明确的。
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)
如果给出的参数没有任何占位符,则它们将被丢弃:
printf "%d", 123
# Gives: 123
printf "%d", 123, 22
# Gives: 123
printf "%d", 123, 22, "\t", "foo", 5566, 12.55, "\n", "blah"
# Gives: 123
字符%
表示“这是一个转换规范”。如果给出了无效的规范,例如未由 定义的规范awk
,则行为为未指定。其他文本被视为普通文本。
printf "Hello %w", "what"
# Usually: Hello %w
# But no guarantee
printf "ABC", "DEF", "GHI"
# Result: ABC
在您的代码中,您经常使用文件输入作为 printf 的格式。如果这些字段不是printf
格式,它们将作为普通文本打印。参数被丢弃。
# 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
您的脚本格式为:
< 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
}
}
'
假设你有:
$ cat pool.sam
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
这会给你(使用上面代码中的编号):
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`
最后结果:
183 +
4
重写可能会让你有所了解:
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
if 语句(有让您感到困惑的危险)也可以一次性写成:
printf "%s", $2 != 16 ? "+" : "-"
阅读格式字符串和printf
.对齐格式通常非常有用,浮点格式等也是如此。
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
输出:
vix : 23
popul : 336
vidi : 42.13
OK 33 +44
最简单的(至少我发现)是在玩游戏时使用脚本而不是命令行。