Grep a primeira linha mais longa
grep -Em1 "^.{$(wc -L <file.txt)}\$" file.txt
O comando é extraordinariamente difícil de ler sem prática, porque combina sintaxe shell e regexp.
Para explicação, usarei primeiro o pseudocódigo simplificado. As linhas que começam com ##não são executadas no shell.
Esse código simplificado usa o nome do arquivo F e deixa de fora citações e partes de regexps para facilitar a leitura.
Como funciona
O comando possui duas partes, a grep- e uma wcinvocação:
## grep "^.{$( wc -L F )}$" F
O wcé usado em uma expansão de processo e $( ... ), portanto, é executado antes grep. Calcula o comprimento da linha mais longa. A sintaxe de expansão do shell é misturada com a sintaxe do padrão de expressão regular de uma maneira confusa; portanto, decompomos a expansão do processo:
## wc -L F
42
## grep "^.{42}$" F
Aqui, a expansão do processo foi substituída pelo valor que retornaria, criando a greplinha de comando usada. Agora podemos ler a expressão regular com mais facilidade: ela corresponde exatamente do início ( ^) ao final ( $) da linha. A expressão entre eles corresponde a qualquer caractere, exceto nova linha, repetida por 42 vezes. Combinadas, ou seja, linhas que consistem em exatamente 42 caracteres.
Agora, voltando aos comandos reais do shell: A grepopção -E( --extended-regexp) permite não escapar da {}legibilidade. Option -m 1( --max-count=1) faz com que pare depois que a primeira linha for encontrada. O <no wccomando grava o arquivo para seu stdin, para evitar que wcimprimam o nome do arquivo junto com o comprimento.
Quais linhas mais longas?
Para tornar os exemplos mais legíveis com o nome do arquivo ocorrendo duas vezes, usarei uma variável fpara o nome do arquivo; Cada um $fno exemplo pode ser substituído pelo nome do arquivo.
f="file.txt"
Mostre a primeira linha mais longa - a primeira linha que contenha a linha mais longa:
grep -E -m1 "^.{$(wc -L <"$f")}\$" "$f"
Mostrar todas as linhas mais longas - todas as linhas que contenham a linha mais longa:
grep -E "^.{$(wc -L <"$f")}\$" "$f"
Mostrar a última linha mais longa - a última linha que é tão longa quanto a linha mais longa:
tac "$f" | grep -E -m1 "^.{$(wc -L <"$f")}\$"
Mostre a linha mais longa - a linha mais longa que todas as outras linhas ou falhe:
[ $(grep -E "^.{$(wc -L <"$f")}\$" "$f" | wc -l) = 1 ] && grep -E "^.{$(wc -L <"$f")}\$" "$f"
(O último comando é ainda mais ineficiente que os outros, pois repete o comando grep completo. Obviamente, ele deve ser decomposto para que a saída wce as linhas escritas por grepsejam salvas nas variáveis.
Observe que todas as linhas mais longas podem na verdade ser todas as linhas Para salvar em uma variável, apenas as duas primeiras linhas precisam ser mantidas.)