繁体   English   中英

如何使用awk进行数字比较并创建列表-在带有CRLF行尾的macOS上使用Awk

[英]how to use awk to do a number comparisons and create a list - using Awk on macOS with CRLF line endings

我试图列出的值大于列出的值(我的knife命令的输出)。 我正在尝试使用awk做到这一点,我一直在研究示例并提出来。 但是,我的预期输出不起作用。

例如,使用此命令,我得到以下输出:

knife ssh -x foobar -a ec2.local_ipv4 "chef_environment:prod AND roles:db_cluster AND AND ipaddress:10.1.*" 'netstat -na | grep EST | wc -l'

输出:

10.1.3.129 2273
10.1.3.130 2533
10.1.3.131 1981
10.1.2.133 1965

现在,我想使用awk因为我只想过滤> 2000的那些值(第二列,删除IP)。

我尝试了以下awk语句,但无济于事

knife ssh -x foobar -a ec2.local_ipv4 "chef_environment:prod AND roles:db_cluster AND AND ipaddress:10.1.*" 'netstat -na | grep EST | wc -l' \
| awk '{if ($2 > 2000) print $2; else echo "Nothing to print"}`

输出:

10.1.3.129 2273
10.1.3.130 2533
10.1.3.131 1981
10.1.2.133 1965

预期产量:

2273
2533

tl; dr

最简单的方法是在将输出传递到awk之前从输出中删除\\r实例:

knife ... | tr -d '\r' | awk ...

假定\\r实例仅作为\\r\\n对的一部分出现以指定行尾,通常是这种情况。


根据您的评论,我们现在知道您的输入具有Windows风格的CRLF( \\r\\n )行尾 ,并且您使用的是macOS Sierra(10.12)

也就是说,示例输出与问题中的awk命令不一致。

抛开这个问题,有两种基本方法

  • 的(a)翻译\\r\\n (CRLF)序列只\\n 第一 (LF)。

  • (b)通过修改Awk的输入记录分隔符来解决此问题。


以下示例使用简化的输入和简化的命令来关注核心问题:

  • printf '10.1.3.129 2273\\r\\n10.1.3.130 2533\\r\\n'用于产生2条CRLF终止( \\r\\n终止)输入行,每行包含2个以空格分隔的字段。

  • awk '{ print $2 }' | cat -e awk '{ print $2 }' | cat -e或其变体-使用awk打印每行中第二个空格分隔的字段,并且cat -e用于可视化输出中的控制字符: $表示\\n (LF)字符。 (在Unix中,该行的末尾),其他控制字符显示为^<letter> ,即,以脱字符号表示 因此, \\r (CR)表示为^M

    • 默认情况下, \\r包含在输出中,因为awk不会将其视为空格(行被空格分隔),这显然是不希望的。 输出如下所示,其中^M表示不希望包含\\r

       2273^M$ 2533^M$ 
    • 通过有效的解决方案, \\r不会包含在输出中,并且输出将如下所示(请注意缺少^M ):

       2273$ 2533$ 

基于方法(a)的解决方案:

最典型的是, 实用程序dos2unix用于将Windows风格的换行符转换为Unix风格的换行符,但是macOS并不附带该实用程序。
但是,可以通过Homebrew轻松安装它。
然后knife ... | dos2unix | awk ... knife ... | dos2unix | awk ... knife ... | dos2unix | awk ...
(或者,先将输出发送到文件,然后在进一步处理之前就地更新该文件: dos2unix file 。)

或者,由无耻自我促进部带给您,您可以安装我的nws CLI 如果安装了Node.js,则只需运行[sudo] npm install -g nws-cli即可安装它,然后使用knife ... | nws --lf | awk ... knife ... | nws --lf | awk ... knife ... | nws --lf | awk ...
(或者,先将输出发送到文件,然后在进行进一步处理之前就地更新该文件:
nws --lf -i file nws还可将LF转换为CRLF,并提供其他与空白相关的功能。)

还有使用库存macOS实用程序的相当简单的方法-请参阅我的答案

使用股票工具的最简单解决方案是使用tr盲目删除任何\\r实例:

$ printf '10.1.3.129 2273\r\n10.1.3.130 2533\r\n' |
    tr -d '\r' | awk '{ print $2 }' | cat -e
2273$
2533$

基于方法(b)的解决方案:

$ printf '10.1.3.129 2273\r\n10.1.3.130 2533\r\n' |
    awk -v RS='\r' 'NF {print $2}' | cat -e
2273$
2533$

注意-v RS='\\r'\\r定义为RS ,即输入记录分隔符,这意味着它会自动从awk读取并拆分为字段的每个记录(行)中排除。

NF是作为操作( {...} )之前的条件放置的,它对于消除因将最终\\n作为单独的记录而读取而导致的空行很有必要。

  • 如果我们可以RS定义为\\r\\n ,则可以避免这种情况,但是可悲的是,macOS上的BSD Awk不支持多字符输入记录分隔符(符合POSIX规范。 )。
    但是,可以通过Homebrew安装GNU Awk,它确实支持此类分隔符,从而可以将命令简化为:
    gawk -v RS='\\r\\n' '{print $2}'

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM