如何打印文件中最长的行?

如何打印文件中最长的行?

我正在寻找打印文件中最长行的最简单方法。我做了一些谷歌搜索,令人惊讶的是似乎找不到答案。我经常打印文件中最长行的长度,但我不知道如何实际打印最长行。谁能提供打印文件中最长行的解决方案?提前致谢。

答案1

cat ./text | awk ' { if ( length > x ) { x = length; y = $0 } }END{ print y }'

UPD: 总结评论中的所有建议

awk 'length > max_length { max_length = length; longest_line = $0 } END { print longest_line }' ./text 

答案2

cat filename | awk '{ print length }' | sort -n | tail -1

答案3

Grep 第一个最长的行

grep -Em1 "^.{$(wc -L <file.txt)}\$" file.txt 

如果不经过练习,该命令非常难以阅读,因为它混合了 shell 语法和正则表达式语法。
为了解释,我将首先使用简化的伪代码。以 开头的行##不在 shell 中运行。
此简化代码使用文件名 F,并省略引用和部分正则表达式以提高可读性。

怎么运行的

该命令有两部分,一个grep- 和一个wc调用:

## grep "^.{$( wc -L F )}$" F

wc用在进程扩展 中,$( ... )因此它在 之前运行grep。它计算最长线的长度。 shell扩展语法与正则表达式模式语法以一种令人困惑的方式混合在一起,所以我将分解进程扩展:

## wc -L F
42
## grep "^.{42}$" F

在这里,进程扩展被替换为它将返回的值,从而创建了grep所使用的命令行。现在我们可以更轻松地读取正则表达式:它从行的开始 ( ^) 到结束 ( ) 完全匹配。$它们之间的表达式匹配除换行符之外的任何字符,重复 42 次。组合起来,即由 42 个字符组成的行。


现在,回到真正的 shell 命令:grep选项-E( --extended-regexp) 允许不转义{}以提高可读性。选项-m 1( --max-count=1) 使其在找到第一行后停止。命令<中的将wc文件写入其标准输入,以防止wc打印文件名和长度。

哪条线最长?

为了使示例在文件名出现两次的情况下更具可读性,我将使用一个变量f作为文件名;$f示例中的每个都可以替换为文件名。

f="file.txt"

显示第一条最长的线- 与最长的行一样长的第一行:

grep -E -m1 "^.{$(wc -L <"$f")}\$" "$f"

展示所有最长的线路- 与最长线一样长的所有线:

grep -E "^.{$(wc -L <"$f")}\$" "$f" 

显示最后最长的一行- 最后一行与最长的一行一样长:

tac "$f" | grep -E -m1 "^.{$(wc -L <"$f")}\$"

显示单条最长线- 最长的线比所有其他线都长,否则失败:

[ $(grep -E "^.{$(wc -L <"$f")}\$" "$f" | wc -l) = 1 ] && grep -E "^.{$(wc -L <"$f")}\$" "$f" 

(最后一个命令比其他命令效率更低,因为它重复了完整的 grep 命令。显然应该对其进行分解,以便将 的输出wc和写入的行grep保存到变量中。
请注意,所有最长的行实际上可能都是所有行为了保存在变量中,只需保留前两行。)

答案4

sed -rn "/.{$(<file expand -t1 |wc -L)}/{p;q}" file

这首先读取命令替换中的文件并输出最长行的长度(之前expand将制表符转换为空格,以克服wc -L- 行中的每个制表符都会添加8 个而不是 1 个到线路长度)。然后将该长度用在sed表达式中,其含义是“找到一个包含该字符数的行,打印它,然后退出”。因此,这实际上可以是最佳的,因为最长的行接近文件顶部,呵呵(感谢提供的精彩和建设性评论)。

另一种,我早于 sed 想到的(在 bash 中):

#!/bin/bash
while read -r line; do
    (( ${#line} > max )) && max=${#line} && longest="$line"
done
echo "$longest"

相关内容