使用 Awk 和正则表达式格式化输出

使用 Awk 和正则表达式格式化输出

我有大约 20 个文件,大约 300 行长,填充的数据格式如下:

62640 usec, 3500 usec
1640 usec, 480 usec
360 usec, 520 usec
1200 usec, 500 usec
340 usec, 520 usec

我想将其转换为 Arduino 代码,格式如下

delayMicroseconds(62640);
pulseIR(3500);
delayMicroseconds(1640);
pulseIR(480);
delayMicroseconds(360);
pulseIR(520);
delayMicroseconds(1200);
pulseIR(500);
delayMicroseconds(340);
pulseIR(520);

依此类推,其中delayMicroseconds()函数中的数字是每行的第一个数字,pulseIR()函数中的数字是每行的第二个数字。

有任何想法吗?我觉得这在 awk 中应该是可能的。

答案1

这里不需要任何正则表达式 - 只需printf将字段格式化为字符串:

$ awk '{printf("delayMicroseconds(%d);\npulseIR(%d);\n", $1, $3)}' file
delayMicroseconds(62640);
pulseIR(3500);
delayMicroseconds(1640);
pulseIR(480);
delayMicroseconds(360);
pulseIR(520);
delayMicroseconds(1200);
pulseIR(500);
delayMicroseconds(340);
pulseIR(520);

答案2

你可以试试这个:

    #!/bin/bash
    cat file |sed '1d' | while IFS= read line; do

    n1=$(echo $line | awk '{print $1}')
    n2=$(echo $line | awk '{print $3}') 

    echo "
    delayMicroseconds($n1);
    pulseIR($n2);
    "
    done

delayMicroseconds(62640);
pulseIR(3500);
delayMicroseconds(1640);
pulseIR(480);
delayMicroseconds(360);
pulseIR(520);
delayMicroseconds(1200);
pulseIR(500);
delayMicroseconds(340);
pulseIR(520);

或者您可以尝试perl如下;

perl -pe 's/(\d+)[\D]+(\d+)[\D]+/delayMicroseconds($1);\npulseIR($2);\n/' file
delayMicroseconds(62640);
pulseIR(3500);
delayMicroseconds(1640);
pulseIR(480);
delayMicroseconds(360);
pulseIR(520);
delayMicroseconds(1200);
pulseIR(500);
delayMicroseconds(340);
pulseIR(520);

答案3

使用 GNU sed:

$ sed -Ee 's/([0-9]+) usec, ([0-9]+) usec.*/delayMicroseconds(\1);\npulseIR(\2);/' < data 
delayMicroseconds(62640);
pulseIR(3500);
...

-E告诉sed使用扩展正则表达式(*),该s/pattern/replacement/命令在当前行上运行搜索替换操作(sed重复为每个输入行给出的指令)。

该模式([0-9]+) usec, ([0-9]+) usec.*意味着[0-9]任何一位数字、+任何数量的前一个“原子”,并(...)保存(“捕获”)任何匹配的内容。 so([0-9]+)表示任意个任意数字,并保存结果。字母按原样匹配,最后的字母.*匹配任意数量的任意字符,只是为了在行尾吃掉任何可能的垃圾。

在替换中,\1and\2被替换为组中保存的内容(...)(但括号本身是字面意思), and\n表示换行符(可能不适用于所有seds)。


(*)为什么我的正则表达式在 X 中有效但在 Y 中无效?了解不同正则表达式类型之间的差异。此外,还有许多sed在线教程。我建议找到一两个并尝试一下,至少让自己熟悉该s///命令。

答案4

使用 GNU awk:

awk -v RS=' usec[,\n] ?' '{print (NR%2?"delayMicroseconds":"pulseIR")"("$0")"}' file

这是使用字符串usec作为记录分隔符。这允许将每个数字捕获为不同的记录,因此该print命令交替显示带有所需数字的 2 个字符串。

相关内容