Как отключить строки, которые длиннее, чем некоторая ширина и маркировка строк, которые были обрублены с замещающим знаком?
Только строки, которые были на самом деле сокращены, должны быть отмечены, но не строки, которые имели просто правильную длину во-первых.
Я хотел бы использовать команду в конвейере.
Это усечет строку, обрубит еще три символа и добавит "...", если длина будет дольше, чем значение, Вы предоставляете в качестве параметра.
other_programs | \
awk -v len=40 '{ if (length($0) > len) print substr($0, 1, len-3) "..."; else print; }'
Некоторые возможности:
с sed
sed -E 's/(.{N})(.{1,})$/\1.../' file
немного более изящно с жемчугом (использующий 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...
Обратите внимание, что, вместе с другими решениями, которые были представлены до сих пор, это отлично не ограничит выходную ширину в присутствии символов, которые отображаются больше чем один столбец шириной, такие как горизонтальные вкладки.
Принятый ответ, записанный как функция с примером, также помещая... посреди строки, а не конца:
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"
}
Попробуйте это:
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'
Другой perl
решение:
perl -ple '$_ = sprintf "%.70s...", $_ if length > 70' file