Анализ файла, разделенного запятыми, в скрипте bash с циклом while
Я пытаюсь проанализировать файл, разделенный запятыми, как показано ниже, и извлечь каждое поле в переменную:
bob,mechanic,single,swimming,/bob/tmp,batman,
joe,architect,married,tennis,/joe/tmp,superman,34
С помощью этого скрипта:
#!/bin/bash
#|| [[ -n "$input" ]]
while IFS=, read -r a b c d e f g; do
echo "$a"
done < "commafile.txt"
Но когда я запускаю сценарий (называемый parsecommas) с./parsecommas из командной строки, сценарий немедленно завершается без вывода.
Что я делаю неправильно? Я использую OSX Yosemite и использую xcode для редактирования скрипта, а затем терминал для его запуска. Я проверил на наличие неисправных невидимых, но не нашел ни одного. commafile.txt находится в той же директории, что и parsecommas bash-скрипта.
РЕДАКТИРОВАТЬ: После запуска программы на С ++ и возможности прочитать только последнюю строку файла, я понял, что эта проблема может быть связана не с моим кодом, а с методом, который я использовал для создания текстовых файлов. я использовал
touch commafile.txt
чтобы создать мой файл, и я смог прочитать только последнюю строку файла при использовании getline (file, line) в программе на C++. Кто-нибудь еще сталкивался с этой проблемой раньше? Что может быть не так с моим Mac/Text Editor?
cat commafile.txt
Печатает только последнюю строку в файле, в то время как при открытии файла в XCode или TextEditor отображаются все строки. Я скопировал и вставил содержимое слова doc в поле в форме поля в commafile.txt.
1 ответ
Если cat filename
печатает только последнюю строку, это означает, что ваш файл почти наверняка использует CR (возврат каретки, \r
), а не LFs (\n
) или CRLF (\r\n
) новые строки. Вы можете воспроизвести эту ошибку, создав файл следующим образом: printf '%s\r' "bob,mechanic,single,swimming,/bob/tmp,batman," "joe,architect,married,tennis,/joe/tmp,superman,34" >commafile.txt
Это приводит к cat
показывает только последнюю строку файла, потому что \r
Символ заставляет курсор возвращаться к началу той же строки при переходе между записями. Это объясняет вашу ошибку, потому что read
Встроенная оболочка ожидает допустимую строку UNIX, которая заканчивается \n
; если ваш код не содержит \n
с, тогда read
вернет ложное значение и цикл не запустится.
Вы можете исправить это следующим образом:
# replace \r characters with \n
tr '\r' '\n' <commafile.txt >commafile.fixed && mv commafile{.fixed,.txt}
Кроме того, вы можете изменить цикл, чтобы он ожидал этот формат вместо стандартного текстового файла UNIX, передав -d $'\r'
в read
:
while IFS=, read -r -d $'\r' a rest; do
printf '%s\n' "$a" # less buggy than echo
done