Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unix命令Awk:查找文件中最长的字符串_Unix_Command Line_Awk - Fatal编程技术网

Unix命令Awk:查找文件中最长的字符串

Unix命令Awk:查找文件中最长的字符串,unix,command-line,awk,Unix,Command Line,Awk,我知道这可能是个老问题,很多人已经解决了;然而,我的版本需要一些扭曲 所以我有一个文件,我叫它quest。对于这里的相似性,它只有4个条目: 约翰 克里斯蒂娜 克里斯汀 汤姆 现在,我想用awk来获取这个文件中最长的名字,我想让它同时返回Christina和Christine 这就是我到目前为止所做的: <quest awk '{ if(length>x) {x =length; y=$0} } END {print y}' 您可以使用以下选项: $ awk '{cur=lengt

我知道这可能是个老问题,很多人已经解决了;然而,我的版本需要一些扭曲

所以我有一个文件,我叫它quest。对于这里的相似性,它只有4个条目:

约翰

克里斯蒂娜

克里斯汀

汤姆

现在,我想用awk来获取这个文件中最长的名字,我想让它同时返回Christina和Christine

这就是我到目前为止所做的:

<quest awk '{ if(length>x) {x =length; y=$0} } END {print y}'

您可以使用以下选项:

$ awk '{cur=length($0)} FNR==NR{max=(cur>max?cur:max); next} cur==max' file file
Christina
Christine
它使用语法
awk'…'file file
在文件中循环两次:

  • 第一次获取最大值-并将其存储在
    max
    变量中。这是
    FNR==NR{}
    块,以
    next
    结束以停止处理当前行。更多信息请访问
  • 第二次打印长度为
    max
    的行

请注意使用
max=(cur>max?cur:max
来设置最大值。这是一个三元运算符,可以这样理解:要设置
max
请检查
cur>max
。如果是这样,则
max=length($0)
;否则,
max=max
您可以使用数组来存储(到目前为止)最长的行

注:

  • maxlength
    存储迄今为止最长行的长度
  • arr
    存储迄今为止最长的行
  • i
    存储数组中的行数
  • split(“,arr)
    初始化
    arr
    为空数组
这样,您就不必读取文件两次,因此也可以在管道中使用它

$ awk '{cur=length($0); recs[cur] = recs[cur] $0 ORS; max=(cur>max?cur:max)} END{printf "%s", recs[max]}' file
Christina
Christine
如果您的文件太大,且上面的内容存在内存问题,则:

$ awk '{cur=length($0)} cur>max{recs=""; max=cur} cur>=max{recs = recs $0 ORS} END{printf "%s", recs}' file
Christina
Christine

您已经了解了许多awk解决方案。 我还想提到,这也可以在perl中完成:

perl -lne '$m<($l=length($_))?$m=$l:0;
           push @{$x{$l}},$_;
           END{print "@{$x{$m}}"} ' your_file

perl-lne'$mThanks感谢您的帮助!我确实理解缩写(x?T:F),但我不确定您是如何在文件中循环两次的…另外,我可以使用@VictoriaJ。请参阅更新的答案。引用引用参考,“因此,条件NR==FNR仅在awk读取第一个文件时为真”。关于第二个问题,不,您必须使用
awk'…'文件
+1您可以避免多次使用变量调用length(),并且需要将三元表达式括起来以便于移植:
awk'{cur=length($0)}FNR==NR{max=(cur>max?cur:max);next}cur==max'文件file
@EdMorton非常感谢您的
{cur=length($0)}
有很多意义,代码看起来更干净。此外,还可以将三元括号括起来。这种解决方案在输入量较小的情况下很好,但由于它存储了所有不适合通过它传输大量数据的内容,我想是的,如果这真的是用户的问题,那么删除REC就很简单了[]每次max增加或仅使用变量而不是数组时。我为这种情况添加了一个替代方案。wrt
我更喜欢单行
-任何程序都可以在单行中编写,因此这不是解决方案的有用标准。此外,对输入使用重定向而不是将文件名指定为awk arg会删除您的可用性如果您的需求在某些方面发生了变化,那么脚本中文件名的可扩展性将很难在将来得到增强。
perl -lne '$m<($l=length($_))?$m=$l:0;
           push @{$x{$l}},$_;
           END{print "@{$x{$m}}"} ' your_file