这是我的样本文件。实际数据中有更多的数据。
wolf@linux:~$ more log*
::::::::::::::
log1.csv
::::::::::::::
hostname,sn,type,ip,random
abc,a11,zzz,192.168.168.168,rrr
def,e16,yyy,192.168.168.169,fff
ghi,k16,yyy,192.168.168.170,ggg
::::::::::::::
log2.csv
::::::::::::::
hostname,sn,ip,random
abc,a11,192.168.168.168,rrr
def,e16,192.168.168.169,fff
ghi,k16,yyy,192.168.168.170,ggg
wolf@linux:~$ 某些数据(如主机名)总是位于第一列中。因此,使用awk -F, '{print $1}'很容易获得它们
wolf@linux:~$ awk -F, '{print $1, $4}' log*
hostname ip
abc 192.168.168.168
def 192.168.168.169
ghi 192.168.168.170
hostname random
abc rrr
def fff
ghi 192.168.168.170
wolf@linux:~$ 问题是,根据日志文件中的数据,这些IP地址位于不同的列中。
如何使用grep只获取主机名& IP的列?
wolf@linux:~$ awk -F, '/def/ {print $1, $4}' log*
def 192.168.168.169
def fff
wolf@linux:~$ 。
wolf@linux:~$ awk -F, '/def/ {print $1, $3}' log*
def yyy
def 192.168.168.169
wolf@linux:~$ 期望输出
def 192.168.168.169
def 192.168.168.169发布于 2021-03-29 12:23:04
如果数据字段在每个文件中的标题行后面,您可以这样做:
awk -F, 'FNR==1{ for(i=1; i<=NF; i++) if($i=="ip") break; next }
{ print $1, $i }' log*.csv发布于 2021-03-29 12:34:50
使用csvkit:
$ csvcut -c hostname,ip log1.csv
hostname,ip
abc,192.168.168.168
def,192.168.168.169
ghi,192.168.168.170
$ csvcut -c hostname,ip log2.csv
hostname,ip
abc,192.168.168.168
def,192.168.168.169
ghi,yyycsvcut命令的工作方式有点像标准的cut命令,但可以使用标头信息提取命名列。
请注意,这依赖于每个文件中的头实际上是正确的。
发布于 2021-03-29 20:42:18
当您拥有具有标题的文件时,通常最好先创建标题标记(名称)到字段(列)顺序的映射,如下面的数组f[]中所存储的那样,然后您可以通过取消引用按字段名索引的数组来获得字段值。这样,无论每个输入文件中列的顺序如何,脚本都会工作:
$ cat tst.awk
BEGIN { FS="," }
FNR==1 {
delete f
for (i=1; i<=NF; i++) {
f[$i] = i
}
next
}
$(f["hostname"]) == h { print $(f["hostname"]), $(f["ip"]) }$ awk -v h='def' -f tst.awk log*.csv
def 192.168.168.169
def 192.168.168.169https://unix.stackexchange.com/questions/642608
复制相似问题