Как работает awk -F?

Не могли бы вы объяснить, как работает следующий фрагмент кода?

l_Basename="hello_world.ksh"

l_THIS_FILE=`echo $l_Basename | awk -F. '{field=1
             while (field < NF) {
                 printf $field
                 if (field < NF - 1) {
                     printf "."}
                 field++} 
             printf "\n"}'`

2 ответа

Решение

-F. устанавливает разделитель полей на .: Дана строка a.b.c., awk увидит четыре поля: a, b, c, а также (пустое поле).

field=1
while (field < NF) 
{
     printf $field
     if (field < NF - 1) 
     {
         printf "."
     }
     field++
}
  • Код зацикливается на каждом поле и печатает его. Обратите внимание, что field начинается с 1, так как поле 0 - это вся строка (или запись, если быть точным). Так как проверка < NF никогда не достигает последнего поля.
  • До второго последнего поля, оно добавляет . предположительно в качестве разделителя полей для какой-либо другой программы.

Все говорят, что этот код является сложным способом реализации basename, команда, часто используемая для удаления расширения из имени файла:

$ basename hello_world.ksh .ksh
hello_world

Даже в awk более кратким способом было бы уменьшить количество полей на единицу: NF-- и установите разделитель поля вывода на ., так что он автоматически добавляется между полями:

$ echo hello_world.ksh | awk -F. -v OFS=. '{NF--}1'
hello_world

Опция "-F" позволяет изменить символ Awk "разделитель полей". Awk рассматривает каждую строку входных данных как составную из нескольких "полей", которые по сути являются словами, разделенными пробелами. Пробел (или символ табуляции) является "разделителем полей" по умолчанию. В некоторых случаях входные данные могут быть разделены другим символом, например, ":", и было бы неплохо иметь возможность указать Awk использовать другой разделитель полей. Это то, что делает опция "-F". Чтобы вызвать Awk и указать ":" в качестве разделителя полей, мы пишем:

awk -F: ...

В этом случае разделителем полей является "."

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