是否有一行命令可以打印目录中文件中最长的行?

是否有一行命令可以打印目录中文件中最长的行?

假设我位于一个包含很多文件的目录中。如何搜索目录中所有文件的内容并显示包含字符串“ER”但不包含“Cheese”的最长行?

到目前为止,据我所知,我正在尝试用一行命令来完成此操作。

我想我需要使用 grep -r 进行递归,以便搜索目录中的所有文件,但我的最终目标是只显示最长的行,所以我认为到目前为止它应该是这样的:

grep -r -e "ER" 

当我出于小小的希望而附加-v“奶酪”时,它当然不起作用。

这不是用一行命令就可以实现的吗?如果是这样,我需要在多行中做什么?

答案1

这是一个 awk 解决方案:

 awk '/ER/ && !/Cheese/ {if (length($0) > maxlen) { maxline=$0; maxlen=length($0);}} END {print maxlen, maxline;}' *

(它还打印最长行的长度,但如果您不想这样做,只需说... END {print maxline;}.

相对于 Jeremy Dover 的 grep 解决方案的优点是它只传递一次输入。缺点是,如果有多行具有相同的最大长度,则仅打印第一行(如果使用 >= 比较长度,则仅打印最后一行); grep 解决方案打印所有这些。

答案2

这一行将满足您的要求(对于一个目录中的文件):

awk '{l=length($0)}/ER/&&!/Cheese/&&(length($0)>l){l=length($0);line=$0}END{print(line)}' *

如果有多行匹配,则仅打印第一的包含 ER(而不是 Cheese)且比之前选择的行更长的行。

此外,这将扫描 pwd (*) 中的文件。如果需要递归,则需要使用查找命令选择文件。

find . -type f -iname '*.sh' -exec sh -c 'awk '\''{l=length($0)}/ER/&&!/Cheese/&&(l>lm){lm=l;li=$0}END{print(li)}'\'' "$@"' awksh {} +

或者分几行(为了可读性):

find . -type f -iname '*.sh' -exec sh -c '\
awk '\''{l=length($0)}/ER/&&!/Cheese/&&(l>lm){lm=l;li=$0}END{print(li)}'\'\
' "$@"' awksh {} +

答案3

awk '/ER/ && !/Cheese/ && length > m {
       m=length; d=$0; f=substr(FILENAME, 3); n=FNR
     }
     END { print m, f ":" n, d }' ./*

假设当前目录中只有常规文件,这将打印满足问题 ( m) 中的条件的最长行的长度,以及找到该文件的文件名 ( f)、行号 ( n) 和行本身 ( d)。

输出可能类似于

8 file:3 Hello ER

最长的一行有 8 个字符长,可以在名为 的文件的第 3 行找到file

答案4

在前面添加字符串的长度,按数字排序,然后打印第一个结果的第二个字段以获取原始字符串。

 grep -h ER * | grep -v Cheese | awk '{ print length($0) " " $0}' | sort -nr| head -1| awk '{print $2}'    

如果需要,此方法允许您执行比“MAX”或“MIN”更复杂的查询。注意AWK的使用。这正是它真正的好处。

相关内容