Подтвердить что ты не робот

Bash: читайте файл по очереди и обрабатывайте каждый сегмент как параметры для другого прога

У меня есть какая-то грязная работа, поэтому Bash script кажется хорошим выбором. Я новичок в Bash, и этот опыт заставляет меня расстраиваться.

Файл mapfiles.txt состоит из следующих строк. Каждая строка имеет четыре сегмента, разделенных пробелом. Каждый сегмент представляет входной параметр для внешнего имени программы "prog". Например, "cm19_1.png" - это имя файла, "0001" индекс, "121422481" долгота и "31035995" широта.

Файл: mapfiles.txt

cm19_1.png 0001 121422481 31035995
cm19_2.png 0002 121423224 31035995
cm19_3.png 0003 121423967 31035995
…

Я хочу выполнить аналогичные команды для каждой строки. Как показано ниже, порядок параметров ввода prog немного отличается. Поэтому имеет смысл написать Bash script для обработки повторяющейся работы.

[Usage] prog <index> <longitude> <latitude> <filename>
example: prog 0001 121422481 31035995 cm19_1.png

Как правило, Bash script будет работать следующим образом:

  • Прочитайте одну строку из mapfiles.txt
  • Разделить сегменты
  • Вызвать программу с правильным порядком параметров

Здесь выполняется run.sh.

#!/bin/sh

input=mapfiles.txt
cmd=prog

while read line
do
        file=$(echo $line | cut -d' ' -f1)
        key=$(echo $line | cut -d' ' -f2)
        log=$(echo $line | cut -d' ' -f3)
        lat=$(echo $line | cut -d' ' -f4)
        echo $cmd $key $log $lat $file
done < "$input"

Я ожидал

prog 0001 121422481 31035995 cm19_1.png
prog 0002 121423224 31035995 cm19_2.png
prog 0003 121423967 31035995 cm19_3.png
… 

АКТУАЛЬНЫЙ результат, который я получил,

 cm19_1.png21422481 31035995
 cm19_2.png21423224 31035995
 cm19_3.png21423967 31035995

Проблемы, которые смутили меня

  • Где "прог"?
  • Где пробел?
  • Что не так с порядком параметров?

Хмм... Я написал этот script на своем Mac с помощью vim и скопировал его в ящик Scientific Linux и коробку gentoo. Эти три парня получают те же смешные результаты.

4b9b3361

Ответ 1

Вы можете упростить это:

while read file key log lat
do
  echo $cmd $key $log $lat $file
done < "$input"

Ответ 2

Используя GNU Parallel, вы можете сделать это в одной строке +, вы можете сделать это параллельно:

cat mapfile.txt | parallel --colsep '\s' prog {2} {3} {4} {1}

Смотрите видеоролики, чтобы узнать больше: http://www.youtube.com/watch?v=OpaiGYxkSuQ

Ответ 3

prog может исчезнуть, потому что $cmd не экспортируется. Ваша версия /bin/sh может выполнить оператор while в отдельной оболочке. Это не должно быть так, и это не относится к моей установке bash, но, возможно, ваша работа ведет интересным образом в этом отделе.

UPD Я вижу, что у вас есть несколько ящиков, которые дают одинаковые результаты. Это делает теорию подоболочки маловероятной. Возможно, у вас есть несколько забавных символов в вашем script и/или исходном файле.

Я скопировал и вставил ваш script и ваш исходный файл в свой блок gentoo, и он дает ожидаемые результаты. Возможно, вам следует сделать то же самое и сравнить файлы с вашими оригинальными.