Укоротить линии, добавив многоточие "..."
Как отрезать линии, которые длиннее некоторой ширины, и пометить отрезанные многоточием многоточие?
Должны быть отмечены только те линии, которые были фактически укорочены, но не те линии, которые изначально имели правильную длину.
Я хотел бы использовать команду в конвейере.
6 ответов
Это обрежет строку, отрежет дополнительные три символа и добавит "...", если длина больше значения, которое вы указали в качестве параметра.
other_programs | \
awk -v len=40 '{ if (length($0) > len) print substr($0, 1, len-3) "..."; else print; }'
Попробуй это:
awk -F '' '{if (NF > 70) {print substr($0, 0, 71)"..."} else print $0}'
Если NF слишком высока, проще:
awk '{if (length($0) > 70) {print substr($0, 0, 71)"..."} else print $0}'
или более короткая версия:
awk 'length > 70{$0=substr($0,0,71)"..."}1'
Некоторые возможности:
с седом
sed -E 's/(.{N})(.{1,})$/\1.../' file
немного более элегантно с Perl (используя lookbehind)
perl -pe 's/(?<=.{N}).{1,}$/.../' file
где N
количество символов, после которого вы хотите заменить его многоточием.
awk
, sed
, а также perl
, как представлено в других ответах, превосходен в обработке текста и, вероятно, является лучшим инструментом для работы.
Но вы также можете сделать это в чистом виде bash
(т. е. "не выходя из оболочки"), если вам нравится:
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
замещать 70
с максимальной желаемой длиной, и filename
с входным файлом.
Чтобы использовать это в правой части канала (т. Е. Передать в него выходные данные другой команды), удалите < filename
и либо установить n
заранее или приложить все это в { ... ;}
:
{ n=70
while read -r; do
if ((${#REPLY}<=n))
then printf '%s\n' "$REPLY"
else printf '%s...\n' "${REPLY:0:$((n-3))}"
fi
done ;}
(Эта версия в квадратных скобках также отлично работает в других контекстах, в том числе с перенаправлением, как указано выше. В этом случае скобки не нужны, но не вредны.)
Это выглядит так:
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...
Обратите внимание, что, как и в других решениях, которые были представлены до сих пор, это не позволит полностью ограничить ширину вывода при наличии символов, отображающих более одного столбца, например горизонтальных вкладок.
Другая perl
решение:
perl -ple '$_ = sprintf "%.70s...", $_ if length > 70' file
Принятый ответ записывается в виде функции с примером, также помещая... в середине строки, а не в конце:
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; }'
}
пример:
parse_branch() {
branch=$(git symbolic-ref --short HEAD || hg branch)
truncate "$branch"
}