https://github.com/yedf2/awkj
nodejs version of simplified awk / nodejs版的简化awk
https://github.com/yedf2/awkj
awk command-line nodejs
Last synced: 8 months ago
JSON representation
nodejs version of simplified awk / nodejs版的简化awk
- Host: GitHub
- URL: https://github.com/yedf2/awkj
- Owner: yedf2
- Created: 2017-03-16T07:38:37.000Z (almost 9 years ago)
- Default Branch: master
- Last Pushed: 2017-03-17T14:12:34.000Z (almost 9 years ago)
- Last Synced: 2025-04-23T02:21:40.158Z (10 months ago)
- Topics: awk, command-line, nodejs
- Language: JavaScript
- Size: 3.91 KB
- Stars: 9
- Watchers: 1
- Forks: 5
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
awkj --node版本的awk
====
* 使用js,拥有强大的编程能力,无需记忆awk特有语法
* 高效运行,在一个百万行日志处理的测试中,用时仅比awk多30%
### 安装
```sh
sudo npm -g install awkj #需要node6+ 环境
```
### 使用
```sh
echo -e "1 3\n2 5" | awkj 'console.log($2)'
```
* 可使用的预定义变量有:FS NR $n (含义与awk相同) G(用于全局数据的存储)
* END 含义与awk相同
```sh
echo -e "1 3\n2 5" | awkj 'if(NR==1) {G.sum=0;} G.sum+=parseFloat($2); END console.log(G.sum/NR)'
```
### 实现
核心代码如下:
```javascript
let G={NR:0}; // 全局数据
let [body, end] = cont.split('END'); //用户输入的代码分为两部分,前面的body每行执行,END后面的代码结束时执行
eachLine(line=>{
G.NR ++; // G.NR为行号
let fs = line.split(sep); // 把行切分为字段
let obj = {FS:fs.length, $0:line, G, NR:G.NR}; // 构建实参
fs.forEach((e,i)=>obj['$'+(i+1)] = e); //构建$1...$n
//函数内部需要解构obj,并且解构$1...$n,最多解构到$99
G.func = G.func || eval(`obj=>{
let {${Object.keys(obj).join(',')}, ${'a'.repeat(99-fs.length).split('').map((e,k)=>`$${k+1+fs.length}`).join(',')}} = obj;
${body}
}`);
G.func(obj); //根据用户输入构建函数并调用
}, ()=>{ //文件结束的回调
end && eval(`obj=>{let {NR,G}=obj;${end}}`)({NR:G.NR,G}); //构建尾部函数并调用
});
```