2015-05-18 4 views
0

У меня много файлов SQL Teradata (пример кода одного из этих файлов ниже).Bash - метод проверки строк

create multiset volatile table abc_mountain_peak as(
select 
a.kkpp_nip as nip, 
from BM_RETABLE_BATOK.EDETON a 
) with data on commit preserve rows; 

create multiset table qazxsw_asd_1 as (
select 
a.address_id, 
from DE30T_BIOLOB.HGG994P_ABS_ADDRESS_TRE a, 
) with data on commit preserve rows; 

create multiset volatile table xyz_sea_depth as(
select 
a.trip, 
from tele_line_tryt a 
) with data on commit preserve rows; 

CREATE multiset table wsxzaq_zxc_2 AS ( 
SELECT 
a.bend_data 
FROM lokl_station a , 
) WITH data on commit preserve rows; 

CREATE multiset table rfvbgt_ttuop_3 AS ( 
SELECT 
a.heret_bini 
FROM fvgty_blumion a , 
) WITH data on commit preserve rows; 

DROP qazxsw_asd_1; 
DROP wsxzaq_zxc_2; 

.EXIT 

Что мне нужно сделать, это создать сценарий (Баш), которые могли бы проверить, если MultiSet таблицы отбрасываются. Там созданы два вида таблиц:

  • MultiSet таблицы нестабильного (которые не должны быть опущены), и
  • MultiSet таблицы (которые должны быть опущены)

В моем примере кода, 2 из 3 многомножественных таблиц отбрасываются (что правильно), а один из них не является (что неверно). Есть ли у вас какие-либо идеи о том, как создать скрипт, который мог бы подтвердить что-то подобное (предоставить информацию, что одна таблица или некоторые таблицы не удалены)? Я действительно начинаю в bash. Моя идея (может быть неправильной) состоит в том, чтобы создать массив, содержащий имена таблиц мультимножества (но не многосетевые летучие таблицы), а затем создать еще одну таблицу с «drop» и именами упавших таблиц и окончательно проверить, есть ли каждая таблица из первого массива также находится во втором массиве. Что вы думаете? Любая помощь будет с благодарностью оценена.

+0

Какую версию Bash вы используете? Я спрашиваю, потому что ассоциативный массив таблиц может быть хорошим решением, но для этого вам нужна версия bash 4. – cdarke

+0

GNU bash, версия 4.1.2 (1) -release (x86_64-redhat-linux-gnu) – euro

ответ

1

Вы можете сделать это довольно легко, читая каждую строку в файл, выделить имена таблиц, связанных с multiset table команд в один массив (dropnames), вы затем изолируете имена таблиц, следующие за операциями DROP, в другой массив (droptable). Тогда просто нужно сравнить оба массива, чтобы найти таблицу в одном, которая не находится в другом. Короткий сценарий как следующий будет делать это для вас:

#!/bin/bash 

declare -a tmparray     ## declare array names 
declare -a dropnames 
declare -a droptable 

volstr="multiset volatile table" ## set query strings 
dropstr="multiset table" 

## read all lines and collect table names 
while read -r line; do 

    [[ $line =~ $dropstr ]] && { ## collect "multiset table" names 
     tmparray=($line) 
     dropnames+=(${tmparray[3]}) 
    } 

    [[ $line =~ DROP ]] && {  ## collect DROP table names 
     tmp="${line/DROP /}" 
     droptable+=(${tmp%;*}) 
    } 

    unset array 

done 

## compare droptable to dropnames, print missing table(s) 
if [ ${#dropnames[@]} -gt ${#droptable[@]} ]; then 

    printf "\n The following tables are missing from DROP tables:\n\n" 

    for i in "${dropnames[@]}"; do 
     found=0 
     for j in "${droptable[@]}"; do 
      [ $i = $j ] && found=1 && continue 
     done 
     [ $found -eq 0 ] && printf " %s\n" "$i" 
    done 

elif [ ${#dropnames[@]} -lt ${#droptable[@]} ]; then 

    printf "\n The following tables are missing from DROP tables:\n\n" 

    for i in "${droptable[@]}"; do 
     found=0 
     for j in "${dropnames[@]}"; do 
      [ $i = $j ] && found=1 && continue 
     done 
     [ $found -eq 0 ] && printf " %s\n" "$i" 
    done 

fi 

printf "\n" 

exit 0 

Выход

$ bash sqlfinddrop.sh <dat/sql.dat 

The following tables are missing from DROP tables: 

    rfvbgt_ttuop_3 
+0

Вау! Большое спасибо Дэвиду! Это работает! У меня есть еще один вопрос - как добавить цикл для чтения файлов после файлов из определенного места. Я пробовал цикл «для», но у меня была ошибка «неоднозначной перенаправления», и я не знаю почему. У вас есть время, чтобы дать мне несколько подсказок? – euro

+1

Конечно: 'for i in dat/sql * .dat; do bash sqlfinddrop.sh <"$ i"; done' Значение просто помещает вызов скрипта внутри цикла 'for' и перенаправляет один файл за раз. 'для i в пути/файлах *; выполнить скрипт <"$ i"; done' –

+1

@euro другой вариант - команда 'find':' find path/to/files -name '* .txt "-exec bash -c" ./yourscript.sh <' {} '"\;' * * Примечание: ** вы должны сделать свой скрипт исполняемым. (например, 'chmod 0755 scriptname') Также обратите внимание, что вы можете легко изменить сценарий, чтобы взять имя файла в качестве аргумента и устранить перенаправление. Вы даже можете ответить на них обоих. Это просто означает еще несколько строк кода. –

1

Я хотел бы сделать это в двух частях с использованием СЭД:

Создать список из создает:

sed -ne 's/^.*create multiset \(volatile \)\?table \(\w\+\).*$/\2/Ip' INPUT FILES | sort > creates.txt

Создать список удалений:

sed -ne 's/^.*drop \(\w\+\).*$/\1/Ip' INPUT FILES | sort > drops.txt

Таблицы, которые были созданы и упал:

join creates.txt drops.txt

Таблицы создаются и не упал:

combine creates.txt not drops.txt

+0

Thanks teambob! Ваш метод выглядит великолепно, но у меня есть одна проблема, я имею в виду, с последней строкой вашего кода. Он дает мне информацию «Комбинация: не найден [Нет такого файла или каталога]», и я не знаю, почему, потому что все остальное работает нормально, эти два файла txt создаются с правильными данными «join create.txt drops.txt» также работает. Знаете ли вы, что может быть проблемой? – euro

+0

Комбинат является частью moreutils. Какую ОС вы используете? Некоторая форма Linux?Другим менее аккуратным подходом было бы использование diff – teambob

+0

WIndows 7 64-bit, но у меня также есть виртуальная машина на Linux. – euro

Смежные вопросы