将逗号从字符串的开头移动到中间

时间:2017-04-21 10:18:23

标签: bash printf

对于你们中的一些人来说这可能很容易,但这次我真的生气了!

我使用ssconvert从xlsx文件导出数据,我需要格式化文本以匹配excel文件中使用的实际值。我不能使用format=raw(对于那些知道我在说什么的人)。

问题是: 其中一个值是百分比数列,显示为 00,00%。 在我导出此列的字段时,该值将更改为 0,0000

我需要"转换"它回到00,00%

我做了什么: 其中一个真正的价值是: 63,73%

我知道我可以使用printf格式化输出,使用manual我可以将此数字转换为以下格式:

printf "%'d\n" $((0,6373*10))
63,730

由于两个原因出错

1 即可。要移动2位数的逗号,可以将值乘以100 - > 0.6373 * 100 = 63,73 。但似乎这不适用于我收到此错误的bash:

perc=$(echo $line | awk -F';' '{print $3}') # output is 0,6373 in a while loop
perc=$(($perc*100))
./process_ssconvert.sh: line 24: *100: syntax error: operand expected (error token is "*100")

2 即可。使用printf并将值乘以前所示,输出为63,730。我需要删除最后一位数字(我认为这是错误的程序)。

如何将值0,0000转换为00,00%?

谢谢大家

修改: 根据要求,我会更好地澄清它。

百分比列有366个值(一年中每一天有一个闰年)。 excel包含许多列,因此它包含多个值。

从百分比列中,我导出的格式为0,0000。 ssconvert,没有" raw" format,以这种格式导出这些值。我不能使用" raw"格式。

我发现自己有一个巨大的文本文件,其中包含一些要编辑的列。一个是这个百分比列。

cat ${CSV} | while read line
do 
perc=$(echo $line | awk -F';' '{print $3}') #suppose the value is 0,6373
perc=$(($perc*100)) # here i should convert to 63,73%
echo "$perc" >> ${CSV_FINAL} # and this file will have all the fields correct
done

仅使用百分比列的代码片段(我不能写所有这些,会太多)。

我需要" printf" $ perc使用00,00%格式(百分号也是如此)。

RE-修改

Part of the excel:
col0        col1        col2    col3
01.01.2017  444,3968    63,73%  1165,5614
02.01.2017  458,1546    67,16%  1452,5821
03.01.2017  820,2238    42,20%  1365,5321
04.01.2017  365,9752    68,68%  1055,8002

Part of the csv:
2017/01/01;444,3968;0,6373;1165,5614
2017/01/02;458,1546;0,6716;1452,5821
2017/01/03;820,2238;0,4220;1365,5321
2017/01/04;365,9752;0,6868;1055,8002

Expected ${CSV_FINAL} output:
1483228800;444,3968;63,73%;1165,5614
1483315200;458,1546;67,16%;1452,5821
1483401600;820,2238;42,20%;1365,5321
1483488000;365,9752;68,68%;1055,8002

col0 -> epoch
col1 -> data
col2 -> percentage
col3 -> data
colN -> many more

2 个答案:

答案 0 :(得分:3)

使用GNU awk(由于mktime函数)

awk -F '[;/]' '
   {
   # convert to epoch
   # mktime use time format "YYYY MM DD HH MM SS [DST]"
   t = mktime( sprintf( "20%d %d %d 00 00 00", $1, $2, $3)

   # don t forget date is splitted as field so decal of 2 in field nr
   printf( "%d;%d;%d;%2.2f%%;%f\n", t, $4, $5, 100 * $6, $7)
   }
   ' YourPart.CSV

假设日期为YY / MM / DD

包含所有其他字段的完整版本(并在打印时显示)

awk '
   BEGIN { FS = OFS = ";" }

   {
   split( $1, temp, "/")
   t = mktime( sprintf( "20%d %d %d 00 00 00", temp[1], temp[2], temp[3])

   # work directly on field content
   $1 = t
   $4 = sprintf( "%2.2f", 100 * $4 )
   }

   # print new content
   7
   ' YourPart.CSV

假设里面没有;的字符串(在这种情况下需要调整)

答案 1 :(得分:1)

因此,您希望将字符串"0,0000"转换为"00,00%",并且您可能希望将"1,0000"转换为"100,00%"

看起来输入中的逗号似乎毫无意义 - 只是中国读者的可读性助手(大多数世界组是1000,中国组是10000)。所以删除它,以便你有一个干净的数字:

  input="0,0000"
  clean_input=$(echo $input | sed 's/,//')

这一步很重要 - Bash(和大多数编程语言)不会将1,000解释为千。它会看到两个以逗号分隔的数字(1000)。因此,$((0,6373*10))没有按照您的想法进行操作:评估逗号之前的数字然后丢弃,以便$((9,6373*10))也评估为63730

要获得小数位数,除以100:

  divided=$(bc <<< "scale=2; $clean_input / 10")

或者更简单地说,使用sed在最后两个字符之前添加.

  divided=`echo $clean_input | sed 's/\(..\)$/.\1/'

现在,您可以在divided中使用printf

  dot_formatted=$(printf "%05.2f%%" $divided)

dot_formatted现在包含00.00%

最后,您可以用逗号替换.

  comma_formatted=$(echo $dot_formatted | sed 's/\./,/')

如果您愿意,可以使用bash内置函数代替sed - 它们的理解程度较低但速度稍快。