我需要在 grep 的结果上加上 0,这样我的脚本格式就可以了,但我不知道该怎么做。这是我的 grep 结果:
261 : 261 = 0 | 1192 : 1184 = 8 |
283 : 283 = 0 | 666 : 659 = 7 |
267 : 267 = 0 | 631 : 620 = 11 |
283 : 283 = 0 | 787 : 781 = 6 |
278 : 279 = -1 | 963 : 957 = 6 |
我希望输出这样的内容:
261 : 261 = 000 | 1192 : 1184 = 0008 |
283 : 283 = 000 | 0666 : 0659 = 0007 |
267 : 267 = 000 | 0631 : 0620 = 0011 |
283 : 283 = 000 | 0787 : 0781 = 0006 |
278 : 279 = -001 | 0963 : 0957 = 0006 |
为了得到这个结果,这是我的脚本:
count100=`grep -ach "0100 $GivenBIN" $line`
count110=`grep -ach "0110 $GivenBIN" $line`
filename=`echo $line | awk -F"/" '{print $NF}'`
echo -e "$filename $count100 : $count110 = $ans1| $count220 : $count230 = $ans4 |"
答案1
根据您的示例输入和输出,我认为
- 数字列始终由空格分隔;
- 您想要将每个数字列格式化为已知的固定宽度;
- 您希望每个给定列中的每一行具有相同的位数;
- 一列有一个前导符号(空格或
-
)。
这将转换为以下 awk 脚本,该脚本将printf
格式应用于每个数字列。
awk 'BEGIN {
widths[1]=widths[3]=3;
widths[5]=" 4";
widths[7]=widths[9]=widths[11]=4
}
{
for (i in widths) $i = sprintf("%0" widths[i] "d", $i);
print
}'
答案2
这是 4 个 sed 表达式; long but simple
它添加了多余的前导零,然后将左侧和右侧的数字分别修剪为 3 和 4 长。
在一行中构建这样的东西是很困难的,但是当它被布置在多行上时就非常容易了,如最后一个代码部分所示......
printf可能是一个解决方案,但它并不像我最初想象的那么简单,因为负数,即。您的要求是所有负数与正数具有相同的位数.....
所以我抛出这个 sed 方法,因为它确实有效,但可能有更简单的解决方案...
sed -r -e "s/^([0-9]+)( : )([0-9]+)( = )(-)?([0-9]+)( )/00\1\200\3\4\500\6\7/" -e "s/0*([0-9][0-9][0-9])( : )0*([0-9][0-9][0-9])( = )(-)?0*([0-9][0-9][0-9])( )/\1\2\3\4\5\6\7/" -e "s/( )([0-9]+)( : )([0-9]+)( = )(-)?([0-9]+)( .)$/\1000\2\3000\4\5\6000\7\8/" -e "s/( )0*([0-9][0-9][0-9][0-9])( : )0*([0-9][0-9][0-9][0-9])( = )(-)?0*([0-9][0-9][0-9][0-9])( .)$/\1\2\3\4\5\6\7\8/" \
<<'EOF'
261 : 261 = 0 | 1192 : 1184 = 8 |
283 : 283 = 0 | 666 : 659 = 7 |
267 : 267 = 0 | 631 : 620 = 11 |
283 : 283 = 0 | 787 : 781 = 6 |
278 : 279 = -1 | 963 : 957 = 6 |
278 : 279 = -1 | 963 : 954 = -1 |
EOF
这是输出
261 : 261 = 000 | 1192 : 1184 = 0008 |
283 : 283 = 000 | 0666 : 0659 = 0007 |
267 : 267 = 000 | 0631 : 0620 = 0011 |
283 : 283 = 000 | 0787 : 0781 = 0006 |
278 : 279 = -001 | 0963 : 0957 = 0006 |
278 : 279 = -001 | 0963 : 0954 = -0001 |
这是 sed 表达式的更易读的版本。
sed -r \
-e "s/^\
([0-9]+)( : )\
([0-9]+)( = )(-)?\
([0-9]+)( )\
/00\1\200\3\4\500\6\7/" \
-e "s/\
0*([0-9][0-9][0-9])( : )\
0*([0-9][0-9][0-9])( = )(-)?\
0*([0-9][0-9][0-9])( )\
/\1\2\3\4\5\6\7/" \
-e "s/( )\
([0-9]+)( : )\
([0-9]+)( = )(-)?\
([0-9]+)( .)$\
/\1000\2\3000\4\5\6000\7\8/" \
-e "s/( )\
0*([0-9][0-9][0-9][0-9])( : )\
0*([0-9][0-9][0-9][0-9])( = )(-)?\
0*([0-9][0-9][0-9][0-9])( .)$\
/\1\2\3\4\5\6\7\8/" \
答案3
你可以使用 打印函数 命令:它的第一个参数是格式字符串,后面跟着将插入到格式字符串中的其他参数,每个格式说明符一个。
打印字符串的格式说明符是%s
;整数用%d
;打印您可以选择指定总位数(例如 4)和0
用于填充的前导,格式为%04d
;如果您希望始终打印符号,请在字符+
后添加%
,如果您希望仅在数字为负数时打印符号,请在后面添加%
空格字符 ( )。此外,您必须像 通常那样终止格式字符串以
\n
打印最终的行尾。echo
请参阅打印(3)完整列表的手册页。
因此,例如:
count100=grep -ach "0100 $GivenBIN" $line
count110=grep -ach "0110 $GivenBIN" $line
filename=echo $line | awk -F"/" '{print $NF}'
printf '%s %d : %d = % 03d | %s : %d = %04d\n' "$filename" "$count100" "$count110" "$ans1" #...
将以您想要的格式打印行。