Хотя я нахожу использование awk
с пустым разделителем полей несколько «новаторским», самое простое решение, на мой взгляд, — это просто ваше небольшое расширение:
awk -F "" '{print $1 (NF-2) $NF}'
Разумеется, это работает только со словами из трех и более букв. Для обработки общего случая:
awk -F "" '{if (NF>2) print $1 (NF-2) $NF; else print $0}'
В качестве пояснения:
-F ""
ввод разбивается на поля после каждого символа, т. е. каждый символ ввода считается отдельным «полем», доступным через $n
в . ] awk выражения (с n номер поля в диапазоне от 1 доNF
). Кстати, руководство пользователя GNU Awk явно предоставляет такие варианты использования в качестве примеров , так что я исправляю свои предыдущие опасения по поводу использования пустой FS. Тем не менее, обратите внимание, что в руководстве говорится: «Это распространенное расширение; оно не указано в стандарте POSIX».if
количество полей (т.е. символов,здесь )больше двух, выведите первое поле/символ ($1
), вычисленное выражение (NF-2
), которое составляет количество символов между первым и последним, и последнее поле/символ($NF
). Обратите внимание, что используемый здесь вызов print
не создает пробелов между отдельными выходными токенами; это происходит только при разделении аргументов запятыми вместо пробела (см. например.Руководство пользователя GNU Awk). else
просто напечатайте все входное выражение, доступное через$0
Обратите внимание, что если мы подадим два ввода -символов, , например. at
, в первом примере кода мы получили бы нежелательный (, но формально правильный вывод ), например a0t
(, потому что в этом случае между первым и последним )нулевыми символами.
Также обратите внимание , и это важно, что если вы предоставляете строку, содержащую начальные или конечные пробелы для этого awk
вызова, как в echo " hello" | awk
, то эти начальные/конечные пробелы будут рассматриваться как первые /последний символ, что приводит к нежелательному поведению!