Сократите линии, добавив & ldquo; & hellip; & rdquo; эллипсис

Как отрезать линии, длина которых превышает некоторую ширину, и обозначить линии, которые были отрублены с помощью многоточия?

Следует отмечать только строки, которые были фактически сокращены, но не строки, которые только что правая длина в первую очередь.

Я хотел бы использовать команду в конвейере.

1
задан 14 September 2014 в 16:23

4 ответа

Попробуйте следующее:

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'
6
ответ дан 24 May 2018 в 03:43
  • 1
    Извините за эту цитату. Ошибка копирования-макароны. – muru 14 September 2014 в 16:26
  • 2
    Это приведет к ошибке в некоторых инструментах awk, если длина больше max NF. Например, mawk имеет max NF 32767. – cuonglm 14 September 2014 в 16:38
  • 3
    Тот, кто добавил третью версию, не имеет многоточия. – muru 14 September 2014 в 20:25
  • 4
    Извините, мисс опечатка, обновлена. – cuonglm 14 September 2014 в 20:27
  • 5
    @Gnouc благодарит за более короткую команду. Я не очень уверен в быстрых вызовах awk, поэтому я обычно использую более длинные версии. :) – muru 17 September 2014 в 04:15

Некоторые возможности:

с sed
sed -E 's/(.{N})(.{1,})$/\1.../' file
несколько более элегантно с perl (с использованием lookbehind)
perl -pe 's/(?<=.{N}).{1,}$/.../' file

, где N - количество символов, после которых вы хотите заменить на многоточие.

4
ответ дан 24 May 2018 в 03:43
  • 1
    -Е означает, что -е, я полагаю? man sed не знает -E – Blauhirn 1 September 2017 в 03:02
  • 2
    @Blauhirn -E означает E xtended Regular Expression - это эквивалент POSIX флага GNU sed -r или --regex-extended. Он упоминается на информационной странице, я думаю (info sed, затем перейдите к Invoking sed - Параметры командной строки ) – steeldriver 1 September 2017 в 04:37

awk, sed и perl, как представлено в других ответах, превосходят при обработке текста и, вероятно, являются лучшими инструментами для работы.

Но вы также можете это сделать в чистом awk (т. е. «без выхода из оболочки»), если вам нравится:

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 ;}

(Эта версия, заключенная в скобки, также отлично работает в других контекстах, в том числе с перенаправлением, как указано выше. Скобки не нужны в этом случае, но не вредны.) [ ! d12]

Это выглядит так:

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...

Обратите внимание, что вместе с другими решениями, которые были представлены до сих пор, это не сможет полностью ограничить ширину вывода в присутствии символов, которые отображать более одной ширины столбца, например горизонтальные вкладки.

3
ответ дан 24 May 2018 в 03:43

Другое perl решение:

perl -ple '$_ = sprintf "%.70s...", $_ if length > 70' file
0
ответ дан 24 May 2018 в 03:43

Другие вопросы по тегам:

Похожие вопросы: