Isso truncará a string, cortará três caracteres adicionais e adicionará "..." se o tamanho for maior que o valor fornecido como parâmetro.
other_programs | \
awk -v len=40 '{ if (length($0) > len) print substr($0, 1, len-3) "..."; else print; }'
Como cortar linhas com mais de uma largura, e marcando as linhas que foram cortadas com reticências?
Somente as linhas que foram realmente reduzidas devem ser marcado, mas não linhas que tiveram o comprimento certo em primeiro lugar.
Eu gostaria de usar o comando em um pipeline.
Isso truncará a string, cortará três caracteres adicionais e adicionará "..." se o tamanho for maior que o valor fornecido como parâmetro.
other_programs | \
awk -v len=40 '{ if (length($0) > len) print substr($0, 1, len-3) "..."; else print; }'
Tente isto:
awk -F '' '{if (NF > 70) {print substr($0, 0, 71)"..."} else print $0}'
Se a NF for muito alta, a maneira mais simples:
awk '{if (length($0) > 70) {print substr($0, 0, 71)"..."} else print $0}'
ou uma versão mais curta:
awk 'length > 70{$0=substr($0,0,71)"..."}1'
Algumas possibilidades:
com sed
sed -E 's/(.{N})(.{1,})$/.../' file
um pouco mais elegantemente com perl (usando lookbehind)
perl -pe 's/(?<=.{N}).{1,}$/.../' file
onde N
é o número de caracteres após os quais você deseja substituir as reticências.
awk
, sed
e perl
, conforme apresentado nas outras respostas, é excelente no processamento de texto e provavelmente é a melhor ferramenta para o trabalho.
Mas você também pode fazer isso em bash
puro (ou seja, , "sem deixar o shell"), se você quiser:
n=70
while read -r; do
if ((${#REPLY}<=n))
then printf '%s\n' "$REPLY"
else printf '%s...\n' "${REPLY:0:$((n-3))}"
fi
done < filename
Substitua 70
pelo comprimento máximo desejado e filename
pelo arquivo de entrada.
Para usar isso no lado direito de um pipe (ou seja, para canalizar a saída de outro comando para ele), remova < filename
e defina n
antes ou coloque tudo em { ... ;}
:
{ n=70
while read -r; do
if ((${#REPLY}<=n))
then printf '%s\n' "$REPLY"
else printf '%s...\n' "${REPLY:0:$((n-3))}"
fi
done ;}
(Esta versão entre colchetes também funciona bem em outros contextos, incluindo o redirecionamento como acima. Os colchetes são desnecessários nesse caso de uso, mas não são prejudiciais.)
Isso parece:
ek@Ilex:~$ help read | head -5 | { n=70
> while read -r; do
> if ((${#REPLY}<=n))
> then printf '%s\n' "$REPLY"
> else printf '%s...\n' "${REPLY:0:$((n-3))}"
> fi
> done ;}
read: read [-ers] [-a array] [-d delim] [-i text] [-n nchars] [-N n...
Read a line from the standard input and split it into fields.
Reads a single line from the standard input, or from file descr...
if the -u option is supplied. The line is split into fields as...
Observe que, em comum com as outras soluções apresentadas até agora, isso não conseguirá limitar perfeitamente a largura da saída na presença de caracteres que exibem mais de uma coluna de largura, como guias horizontais .
A resposta aceita escrita como uma função com o exemplo, também colocando o ... no meio da string ao invés do final:
truncate() {
echo "$@" | \
awk -v len=15 '{ if (length($0) > len) print substr($0, 1, len-3) "..." substr($0, length($0) - len, length($0)); else print; }'
}
exemplo:
parse_branch() {
branch=$(git symbolic-ref --short HEAD || hg branch)
truncate "$branch"
}
Outra solução perl
:
perl -ple '$_ = sprintf "%.70s...", $_ if length > 70' file
Tags text-processing