Разделите строку по пробелу в ZSH

Вопрос или проблема

Дан файл file.txt:

первая строка
вторая строка
третья строка

Это работает в bash:

while IFS=' ' read -a args; do
  echo "${args[0]}"
done < file.txt

Чтобы получить

первая
вторая
третья

То есть, мы смогли читать файл построчно, и на каждой строке мы дополнительно разбивали строку на массив, используя пробел в качестве разделителя. Но в zsh результатом является ошибка: read: bad option: -a.

Как мы можем добиться в zsh такого же результата, как в bash? Я пробовал несколько решений, но так и не смог разбить строку на массив, используя пробелы в качестве разделителя.

Из man zshbuiltins видно, что в zsh используется -A вместо -a.

read [ -rszpqAclneE ] [ -t [ num ] ] [ -k [ num ] ] [ -d delim ]
     [ -u n ] [ name[?prompt] ] [ name ...  ]
...
       -A     Первое имя принимается как имя массива
              и все слова присваиваются ему.

Следовательно, команда будет следующей

while IFS=' ' read -A args; do
  echo "${args[1]}"
done < file.txt

Обратите внимание, что по умолчанию нумерация массивов в zsh начинается с 1, в то время как в bash — с 0.

$ man zshparam
...
Индексы массивов
...
Элементы нумеруются, начиная с 1, если только не установлена опция
KSH_ARRAYS, в этом случае они нумеруются с нуля.

Поздно, но вот что я использую для разделения по нижним подчеркиваниям в zsh. Может сработать и в других оболочках.

# Разделить по нижним подчеркиваниям
var=
parts=(${(@s:_:)var})
echo $parts
for val in $parts; do
echo $val
done

Вероятно, это будет работать и с пробелами, если заменить нижнее подчеркивание на пробел. Я добавил часть с echo, чтобы вы могли протестировать и увидеть результаты.

Ответ или решение

Сплит строки по пробелам в ZSH: полное руководство

В операционных системах Unix и Linux часто возникает необходимость обрабатывать текстовые файлы, разбивая строки на отдельные слова или элементы. Здесь мы обсудим, как можно разбить строки по пробелам в Z Shell (ZSH), аналогично тому, как это делается в Bash.

Проблема и её решение

Перед нами стоит задача: из файла file.txt извлечь каждую строку и разбить её на слова, используя пробел в качестве разделителя. Рассмотрим содержимое файла:

first line
second line
third line

В Bash для этой задачи мы можем использовать следующий код:

while IFS=' ' read -a args; do
  echo "${args[0]}"
done < file.txt

Этот код читает файл построчно, разбивает каждую строку на массив args, и затем выводит первый элемент (слово) каждой строки. Однако, если попробовать выполнить аналогичную команду в ZSH, мы столкнемся с ошибкой: read: bad option: -a.

Зачем возникает ошибка?

В ZSH команда read использует флаг -A вместо -a. В Bash индексация массивов начинается с нуля, тогда как в ZSH — с единицы. Это важно учитывать для корректной работы с данными.

Корректный код для ZSH

Для реализации аналогичного функционала в ZSH нам нужно использовать -A для объявления массива. Также, поскольку индексация начинается с 1, мы укажем правильный индекс при обращении к элементам массива.

Вот как будет выглядеть код:

while IFS=' ' read -A args; do
  echo "${args[1]}"
done < file.txt

Объяснение кода

  • while IFS=’ ‘: Устанавливает разделитель по умолчанию для read в пробел. Это позволяет разделять входные данные на слова.

  • read -A args: Читает строку и разбивает её на массив args.

  • echo "${args[1]}": Печатает первое слово (индекс 1) из массива args. Если нам нужно вывести все слова, используем цикл:

while IFS=' ' read -A args; do
  for word in $args; do
    echo "$word"
  done
done < file.txt

Дополнительные примеры

Если вам необходимо разделить строку по другим разделителям, можно использовать следующий синтаксис:

var="слово1_слово2_слово3"
parts=(${(@s:_:)var})

for val in $parts; do
  echo $val
done

В этом примере используется разделитель _. Чтобы изменить разделитель на пробел, просто замените символ _ на пробел.

Заключение

Разделение строк по пробелам в ZSH требует некоторой адаптации подхода из Bash. Главные отличия заключаются в синтаксисе команды read и индексации массивов. Понимание этих особенностей поможет вам эффективно обрабатывать текстовые данные в ZSH. Надеюсь, что данное руководство окажется полезным для вас в будущем!

Оцените материал
Добавить комментарий

Капча загружается...