Создание нескольких циклов с чтением строк из файлов ASCII в Bash - PullRequest
0 голосов
/ 25 февраля 2019

Я хочу создать внутренний цикл внутри цикла со строками, которые читаются из файлов ascii в скрипте bash.У меня есть два входных файла ascii, которые содержат список строк:

files.txt:
filename1
filename2


polls.txt:
CO
NOx
SOx

Я использовал IFS и читал следующее:

while IFS= read -r file; do
   printf '%s\n' "$file"

    while IFS= read -r poll; do
       printf '%s\n' "$poll"
       ogrinfo $Database_maindir/$file".shp" -sql "ALTER TABLE $file ADD COLUMN $poll float"
    done < "$Database_maindir/polls.txt"

done < "$Database_maindir/files.txt"

Я получаю следующие распечатки и ошибки:

CO
CO
FAILURE:
Unable to open datasource `/home/CO.shp' with the following drivers.

Читает только строку "polls.txt".

Правильный вывод должен быть:

filename1
CO
ogrinfo /home/"filename1.shp" -sql "ALTER TABLE filename1 ADD COLUMN CO float"
NOx
ogrinfo /home/"filename1.shp" -sql "ALTER TABLE filename1 ADD COLUMN NOx float"
Sox
ogrinfo /home/"filename1.shp" -sql "ALTER TABLE filename1 ADD COLUMN Sox float"

filename2
CO
ogrinfo /home/"filename2.shp" -sql "ALTER TABLE filename2 ADD COLUMN CO float"
NOx
ogrinfo /home/"filename2.shp" -sql "ALTER TABLE filename2 ADD COLUMN NOx float"
Sox
ogrinfo /home/"filename2.shp" -sql "ALTER TABLE filename2 ADD COLUMN Sox float"

Итак, для каждого файла (например, имя_файла1, имя_файла2) я хочу выполнить КОМАНДУ (например, команда ogrinfo, которая обновляет столбцы файла)где столбцы - это разные загрязнители, перечисленные в файле polls.txt.

В первом цикле я хочу прочитать строки из файла files.txt и сохранить строку $ file с именем строки (например, filename1). Во втором цикле я хочу прочитать строки из "polls.txt" и сохранить строку $ poll (например, CO).

Однако, похоже, что для первого цикла он читает строку из первого файла.он находит, что означает «polls.txt», поэтому $ file выдает строку «CO».

Как определить, что первый цикл должен читать второй текстовый файл?

Ответы [ 2 ]

0 голосов
/ 25 февраля 2019
  1. Используйте специальные файловые дескрипторы.Таким образом, вы на 100% уверены, что каждый read читает из правильного потока.И команды внутри цикла также не читаются из потока.

while IFS= read -r -u 3 file; do
   printf '%s\n' "$file"

    while IFS= read -r -u 4 poll; do
       printf '%s\n' "$poll"
       echo ogrinfo $Database_maindir/$file".shp" -sql "ALTER TABLE $file ADD COLUMN $poll float"
    done 4< "$Database_maindir/polls.txt"

done 3< "$Database_maindir/files.txt"
Используйте нечитаемый скрипт, который сначала объединяет два файла, повторяя первый номер с количеством строк во втором, а затем повторяя каждую строку второго с количеством строк в первом, а затем запускает xargs (ideas)для повторения от здесь и здесь )

paste <(
    awk -v nr=$(wc -l <polls.txt) \
        '{for (i = 1; i <= nr; i++) print}' files.txt
) <(
    seq $(wc -l <files.txt) |
    xargs -n1 cat polls.txt
) |
xargs -n2 sh -c 'echo ogrinfo "$1".shp -sql "ALTER TANLE $1 ADD COLUMN $2 float"' --
0 голосов
/ 25 февраля 2019

Возможно, вы можете попробовать с awk:

awk '
  NR == FNR {
    a[$0]
    next
    }
  {
    for ( i in a )
      printf( "system ogringo %s %s\n" , $0 , i )
  }
' polls.txt files.txt

Я ничего не знаю о sql, но, возможно, вы можете иметь только одну команду для каждого файла.

...