加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

shell – 将文件名添加到xargs和awk命令的输出中

发布时间:2020-12-15 21:26:02 所属栏目:安全 来源:网络整理
导读:我有一个完整的.txt文件目录,每个文件有两列和多行( 10000).对于这些文件中的每一个,我试图在第二列中找到最大值,并将第1列和第2列中的相应条目打印到输出文件中.为此,我有一个工作awk命令. find ./ -name "*.txt" | xargs -I FILE awk '{if(max$2){max=$2;d
我有一个完整的.txt文件目录,每个文件有两列和多行(> 10000).对于这些文件中的每一个,我试图在第二列中找到最大值,并将第1列和第2列中的相应条目打印到输出文件中.为此,我有一个工作awk命令.

find ./ -name "*.txt" | xargs -I FILE awk '{if(max<$2){max=$2;datum=$1}}END{print datum,max}' FILE >> out.txt

但是,我还想用每对数字打印相应输入文件的名称.输出看起来像:

file1.txt datum1 max1
file2.txt datum2 max2

为此,我试图从这个类似的问题中汲取灵感:
add filename to beginning of file using find and sed,
但我无法找到一个有效的解决方案.到目前为止,我的最大努力看起来像这样

find ./ -name "*.txt" | xargs -I FILE echo FILE | awk '{if(max<$2){max=$2;datum=$1}}END{print datum,max}' FILE >> out.txt

但我得到错误:

awk: can’t open file FILE
source line number 1

我尝试了各种其他方法,可能是几个字符远离正确:
(1)

find ./ -name "*.txt" | xargs -I FILE -c "echo FILE ; awk '{if(max<$2){max=$2;datum=$1}}END{print datum,max}' FILE" >> out.txt

(2)

find ./ -name "*.txt" -exec sh -c "echo {} && awk '{if(max<$2){max=$2;datum=$1}}END{print datum,max}' {}" ; >> out.txt

我不介意使用什么命令(xargs或exec或其他),我只关心输出.

解决方法

如果所有.txt文件都在当前目录中,请尝试(GNU awk):

awk '{if(max=="" || max<$2+0){max=$2;datum=$1}}ENDFILE{print FILENAME,datum,max; max=""}' *.txt

如果要同时搜索.txt文件的当前目录及其所有子目录,请尝试:

find . -name '*.txt' -exec awk '{if(max=="" || max<$2+0){max=$2;datum=$1}}ENDFILE{print FILENAME,max; max=""}' {} +

因为现代find具有-exec动作,所以很少需要命令xargs.

这个怎么运作

> {if(max ==“”|| max< $2 0){max = $2; datum = $1}} 这将找到最大列2并将其和相应的值保存在第1列中.
> ENDFILE {print FILENAME,max;最大= “”}

到达每个文件的末尾后,将打印文件名以及最大列2的行中的第1列和第2列.

此外,在每个文件的末尾,max被重置为空字符串.

考虑一个包含这三个文件的目录:

$cat file1.txt
1       1
2       2
$cat file2.txt
3       12
5       14
4       13
$cat file3.txt
1       0
2       1

我们的命令产生:

$awk '{if(max=="" || max<$2+0){max=$2;datum=$1}}ENDFILE{print FILENAME,max; max=""}' *.txt
file1.txt 2 2
file2.txt 5 14
file3.txt 2 1

BSD awk

如果我们不能使用ENDFILE,请尝试:

$awk 'FNR==1 && NR>1{print f,max; max=""} max=="" || max<$2+0{max=$2;datum=$1;f=FILENAME} END{print f,max}' *.txt
file1.txt 2 2
file2.txt 5 14
file3.txt 2 1

因为一个awk进程可以分析许多文件,所以这种方法应该很快.

> FNR == 1&& NR> 1 {print f,max;最大= “”}

每次我们开始一个新文件时,我们都会打印上一个文件中的最大值.

在awk中,FNR是当前文件的行号,NR是到目前为止读取的总行数.当FNR == 1&& NR> 1,这意味着我们已经完成了至少一个文件,我们将在下一个文件中启动.
> max ==“”|| max< $2 0 {max = $2; datum = $1; f = FILENAME} 像以前一样,我们捕获第2列的最大值和第1列的相应数据.我们还将文件名记录为变量f.
> END {print f,max}

读完最后一个文件后,打印出最大行.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读