假设有如下full_data.txt文件

> cat full_data.txt
ID|NAME|DATE
1199|abc|20171200
1200|def|20171200
1300|zjd|20171204
1301|dfs|20171205
1303|sdf|20171203
1305|adf|20171201

要求从中找出ID为1200的那些行,显然grep实现起来不那么友好,会将额外的1199|abc|20171200带出来,这时候就需要awk出场了。

创建awk_control.awk控制文件

#!/bin/awk -f
BEGIN {
	_Feed_column=feedcol
	_Src_column=srccol
}
NR==FNR {
	arr[getValue(_Feed_column)]=1
}
NR>FNR {
	FS="|"
	if ((arr[getValue(_Src_column)])) {
		print $0
	}
}

function getValue(column) {
	if (column ~ /^[0-9]+$/) {
		return $column
	}

	if (column ~ /^[0-9]+_[0-9]+$/) {
		split(column, a, "_")
		col1=a[1]
		col2=a[2]
		return $col1"_"$col2
	}
}

END {
}

创建feed.txt引用文件

> cat feed.txt
1200
1300

执行命令, 得到结果

> awk -F "|" -v feedcol=1 -v srccol=1 -f awk_control.awk feed.txt full_data.txt
1200|def|20171200
1300|zjd|20171204

关键点解析

  1. NR, FNR

    • awk官方说明:

      NR: The total number of input records seen so far FNR: The input record number in the current input file

    • 当NR==FNR时,是在读取feed.txt文件,并将关键列的值塞入array中;

    • 当NR>FNR时,在读取full_data.txt文件,碰到关键列值存在时输出整行print $0

  2. getValue函数

    • column ~ /^[0-9]+$/

      判断是否为单纯的列

    • column ~ /^[0-9]+_[0-9]+$/

      判断是否为可并列,按照_分割得出index,再把相应的值拼装起来