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