bash awk - 将负数转换为正数,反之亦然

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9852660/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 01:51:09  来源:igfitidea点击:

awk - Converting negative numbers to positive and vice versa

bashsedawk

提问by user1290065

I have a file with structure like this:

我有一个结构如下的文件:

[05:58:10 08.12.1990] 125.441
[05:58:21 08.12.1990] -2.4158
...

Where everything but the last colummn is some sort of timecode (different for every file) and I need to convert the last number to its opposite, like this:

除了最后一列之外的所有内容都是某种时间码(每个文件都不同),我需要将最后一个数字转换为相反的数字,如下所示:

[05:58:10 08.12.1990] -125.441
[05:58:21 08.12.1990] 2.4158
...

I tried it with awk, but since my knowledge of awk is quite poor I didn't quite achieve it. I first tried to add negative numbers with this:

我用 awk 尝试过,但由于我对 awk 的了解很差,所以我没有完全实现它。我首先尝试用这个添加负数:

awk '{$NF=" "; NF--; printf 
awk '{$NF *= -1; print}'
; NF++; if ($NF ~ /^[0-9].*/){printf "-"; print $NF}}'

but since I throw the last column away with NF--, I can't get it back with NF++.

但是因为我用 NF-- 扔掉了最后一列,所以我无法用 NF++ 取回它。

Any help with this would be appreciated. Thank you.

对此的任何帮助将不胜感激。谢谢你。

回答by William Pursell

Try :

尝试 :

awk '  { if( $NF ~ /^-/ ){sub(/-/, "", $NF); print 
cat data | awk '  { if( $NF ~ /^-/ ){sub(/-/, "", $NF); print 
sed 's/ \([0-9.]*\)$/ -/;t;s/\(.*\)-//' file
[05:58:10 08.12.1990] -125.441
[05:58:21 08.12.1990] 2.4158
;} else { $NF="-"$NF; print
$ txr -c '@(collect)
[@date] @{sign /-?/}@num
@(output)                                                         
[@date] @(if (equal sign "") "-" "")@num   
@(end)   
@(end)' < data.txt
[05:58:10 08.12.1990] 125.441
[05:58:21 08.12.1990] -2.4158
[05:59:30 08.13.2000] 0.94630008768741448848
}} ' [05:58:10 08.12.1990] -125.441 [05:58:21 08.12.1990] 2.4158 [05:59:30 08.13.2000] -0.94630008768741448848
;} else {sub(/^[1-9]*.[1-9]*/,"-"$NF,$NF); print
$ txr -c '@(collect)
@(cases)
[@date] @{sign /-?/}@num
@(or)                                      
@(throw error "invalid data")
@(end)   
@(output)
[@date] @(if (equal sign "") "-" "")@num
@(end)
@(end)' < data.txt
} } ' $ cat data [05:58:10 08.12.1990] 125.441 [05:58:21 08.12.1990] -2.4158 $ cat data | awk ' { if( $NF ~ /^-/ ){sub(/-/, "", $NF); print
## Try to remove the negative sign.
s/\(\] \+\)-\(.*\)$//

## If last substitution succeed, goto label 'a'.
ta

## If last substitution failed, there was not negative sign, so
## it is a positive number, I will have to add the sign just 
## before it.
s/\] \+/&-/

## Label 'a' at end of script. Here print line and read next one.
:a
;} else {sub(/^[1-9]*.[1-9]*/,"-"$NF,$NF); print
[05:58:10 08.12.1990] 125.441
[05:58:21 08.12.1990] -2.4158
} }' [05:58:10 08.12.1990] -125.441 [05:58:21 08.12.1990] 2.4158

回答by wisent

what about:

关于什么:

sed -f script.sed infile

edit: as William Purssell suggested, improved version of this script:

编辑:正如 William Purssell 所建议的,这个脚本的改进版本:

[05:58:10 08.12.1990] -125.441                                                                                                                                                                                                               
[05:58:21 08.12.1990] 2.4158

回答by potong

This might work for you:

这可能对你有用:

##代码##

In essence:

在本质上:

  • If the last field is separated by a space prepend a -
  • Otherwise remove the last minus.
  • 如果最后一个字段由空格分隔,则添加一个 -
  • 否则删除最后一个减号。

回答by Kaz

http://www.nongnu.org/txr

http://www.nongnu.org/txr

##代码##

This is more robust than the hacky solutions that blindly flip a minus sign by column, because we are doing some pattern matching on what the data looks like (and we can increase the amount of detail, if necessary).

这比盲目地逐列翻转减号的hacky解决方案更强大,因为我们正在对数据的外观进行一些模式匹配(并且我们可以在必要时增加细节量)。

But the @(collect)skips stuff that does not match. One thing we can do is throw an exception if there is some oddly shaped row:

但是@(collect)跳过不匹配的东西。我们可以做的一件事是,如果有一些奇怪形状的行,则抛出异常:

##代码##

回答by Birei

Using sed:

使用sed

Content of script.sed:

内容script.sed

##代码##

Content of infile:

内容infile

##代码##

Run it like:

像这样运行它:

##代码##

And result:

结果:

##代码##