Shell 如何在awk中同时格式化字符串和浮点数?

Shell 如何在awk中同时格式化字符串和浮点数?,shell,awk,format,Shell,Awk,Format,我的专栏如下: ifile.txt 1.25 2.78 ? ? 5.6 3.4 我想将浮点格式化为十进制,并跳过字符串 ofile.txt 1 3 ? ? 6 3 Walter A,F.Knorr和Janez Kuhar根据我的问题和类似命令的需要,建议了一些不错的脚本 awk '{printf "%d%s\n", $1}' ifile.txt 同样,我发现我有很多列,但是其他列不需要任何格式。因此,我必须以如下形式使用上述命令: awk '{printf "%5s %d%s %5s %5

我的专栏如下:

ifile.txt
1.25
2.78
?
?
5.6
3.4
我想将浮点格式化为十进制,并跳过字符串

ofile.txt
1
3
?
?
6
3
Walter A,F.Knorr和Janez Kuhar根据我的问题和类似命令的需要,建议了一些不错的脚本

awk '{printf "%d%s\n", $1}' ifile.txt
同样,我发现我有很多列,但是其他列不需要任何格式。因此,我必须以如下形式使用上述命令:

awk '{printf "%5s %d%s %5s %5s %5s\n", $1, $2, $3, $4, $5}' ifile.txt
例如:

ifile.txt
1  1.25   23.2    34  3.4
2  2.78   22.0    23  1.2
3     ?      ?     ?  4.3
4     ?      ?     ?  6.5
5   5.6   45.0     5  2.4
6   3.4   43.0    23  5.6
正如F.Knorr在回答时再次建议的那样,我使用了以下命令:

awk '$2~/^[0-9]+\.?[0-9]*$/{$2=int($2+0.5)}1' ifile.txt > ofile.txt

ofile.txt
1  1 23.2    34  3.4
2  3 22.0    23  1.2
3  ?      ?     ?  4.3
4  ?      ?     ?  6.5
5  6 45.0     5  2.4
6  3 43.0    23  5.6
它工作正常,但需要格式化。像

ofile.txt
1  1   23.2    34  3.4
2  3   22.0    23  1.2
3  ?      ?     ?  4.3
4  ?      ?     ?  6.5
5  6   45.0     5  2.4
6  3   43.0    23  5.6

只需添加一半即可通过以下方法完成:

awk ' $1 ~ /^[0-9]+$|^[0-9]+.[0-9]+$/ { printf("%d\n", $1 + 0.5); next }
      { print $1 } ' file
或稍短一点:

awk ' $1 ~ /^[0-9]+$|^[0-9]+.[0-9]+$/ { printf("%d\n", $1 + 0.5); next } 1' file

只需添加一半即可通过以下方法完成:

awk ' $1 ~ /^[0-9]+$|^[0-9]+.[0-9]+$/ { printf("%d\n", $1 + 0.5); next }
      { print $1 } ' file
或稍短一点:

awk ' $1 ~ /^[0-9]+$|^[0-9]+.[0-9]+$/ { printf("%d\n", $1 + 0.5); next } 1' file

您可以首先检查列是否包含数字(通过regex),然后相应地处理打印:

 awk '$1~/^[0-9]+\.?[0-9]*$/{printf "%i\n",$1+0.5; next}1' test.txt
更新:如果第n列需要如上所述进行格式化(其他列中没有其他格式),则在以下命令中将所有
$1
替换为
$n

awk '$1~/^[0-9]+\.?[0-9]*$/{$1=int($1+0.5)}1' test.txt

您可以首先检查列是否包含数字(通过regex),然后相应地处理打印:

 awk '$1~/^[0-9]+\.?[0-9]*$/{printf "%i\n",$1+0.5; next}1' test.txt
更新:如果第n列需要如上所述进行格式化(其他列中没有其他格式),则在以下命令中将所有
$1
替换为
$n

awk '$1~/^[0-9]+\.?[0-9]*$/{$1=int($1+0.5)}1' test.txt


这是一个良好的工作列。我有很多其他的专栏,但它们不需要格式。你能建议一下如何使用这个吗?
awk'$1~/^[0-9]+$|^[0-9]+[0-9]+$/{printf(“%d\n”、$1+0.5);shift;print$0;next}1'文件
,该文件将像“4x2”这样的字符串转换为数字
4
,因为它的
。它也不适用于负数,但idk如果这些负数可以存在于OPs文件中。@EdMorton是对的,请参阅@F.Knorr(点前的反斜杠,是否有负数(应该减半,而不是加半),您希望如何使用
7.
。一个列可以正常工作。我有许多其他列,但它们不需要格式。您能建议如何使用此列吗?
awk'$1~/^[0-9]+$|^[0-9]+.[0-9]+$/{printf(%d\n,$1+0.5);shift;print$0;next}1'文件
,该文件将像'4x2'这样的字符串转换为数字
4
。它也不适用于负数,但idk(如果负数可以存在于OPs文件中)。@EdMorton是对的,请参阅@F.Knorr(点前的反斜杠,是否有负数)的答案和讨论中的更正(你应该减,而不是加,一半),你想用
7做什么。
。这似乎很好。如果我有很多列,你能建议我如何使用这个命令吗?但是,没有其他列不需要任何格式?非常感谢你更新答案。但是我仍然对所需的格式有问题(我已经更新了我的问题)。我尝试了很多按照我的格式制作,但是没有成功。你介意帮忙吗?问题是你的列被不同数量的空格分隔。默认情况下,awk将任何空格序列视为列分隔符。一个简单的解决方案是使用类似
awk'BEGIN{OFS=“”}$2~/^[0-9]+\。?[0-9]*$/{$2=int($2+0.5)}1'测试
生成一个文件,其中的列由一个空格分隔。如果您想保留原始格式,我需要多考虑一下……非常感谢@F.Knorr。您的建议和帮助现在解决了我的问题。我使用了一个选项卡使用您的命令:
awk'BEGIN{OFS=“\t”}$2~/^[0-9]+\.?[0-9]*$/{$2=int($2+0.5)}1'
这似乎很棒。如果我有许多列,但是没有其他列不需要任何格式,请您建议我如何使用此命令?非常感谢您更新答案。但是,我对所需格式仍有问题(我已更新了我的问题)。我尝试了很多按照我的格式制作,但没有成功。你介意帮忙吗?问题是你的列之间有不同数量的空格。默认情况下,awk将任何空格序列视为列分隔符。一个简单的解决方案是使用类似
awk'BEGIN{OFS=“”}$2~/^[0-9]+\?[0-9]*$/{$2=int($2+0.5)}1'test
生成一个文件,其中的列由一个空格分隔。如果您想保留原始格式,我需要再考虑一下……非常感谢@F.Knorr。您的建议和帮助现在解决了我的问题。我使用了一个选项卡使用您的命令:
awk'BEGIN{OFS=“\t”}$2~/^[0-9]+\.?[0-9]*$/{$2=int($2+0.5)}1'
您的文件中是否有负数?如果有,请在示例中包含两个负数,以便我们可以看到您希望如何将它们向上/向下舍入。还可以包含一些.5值,以便我们可以查看您希望有偏(向上舍入)还是无偏(向偶数舍入)四舍五入或其他!最后-你在评论中说,你的真实输入有多列,所以用多列显示样本输入,这样你和我们就不会浪费时间重新设计潜在的解决方案。始终使你的样本尽可能接近你的真实数据,同时保持足够简洁,以便我们快速/轻松阅读。你能否定吗文件中的ive数字?如果是,请在示例中包含两个数字,以便我们可以看到您希望它们如何向上/向下舍入。还可以包含一些.5值,以便我们可以看到您希望有偏(向上舍入)还是无偏(向上舍入到偶数)四舍五入或其他!最后-你在评论中说你的真实输入有多列,所以用多列显示样本输入,这样你和我们就不会浪费时间重新设计潜在的解决方案。始终使你的样本尽可能接近真实数据,同时保持足够简洁,以便我们快速/轻松阅读。