2015-10-17 2 views
-2
[[email protected] sql]# cat a.sql 
use Test1; 
aaaa 
bbb 
ccc 
use Test2; 
zzzz 
dddd 
use Test3; 
jjj 
use Test1; 
kkk 
lll 

hi all Я хочу разобрать файл в нижнем виде, мне нужно использовать сценарий оболочки, и может ли кто-нибудь помочь мне со сценарием, пожалуйста. Из файла он должен создать отдельный файл на основе^использования и держать добавление следующих строк до более одна пользы приходит поэтому окончательный вывод я нуженАнализ файлов с помощью сценария оболочки

1) Три файлов должны быть созданы

Test1 Test2 Test3

2) если я кошка Test1, Test2 и Test3

$ cat Test1 
aaaa 
bbb 
ccc 
kkk 
lll 


$ cat Test2 
zzzz 
dddd 


$ cat Test3 
jjj 

пожалуйста, помогите мне :-(

ответ

0

Хотя это может показаться простым вначале, сделать это правильно и обработать начальный тест для существующих файлов, усечение, если файл существует, а также обрабатывать повторяющиеся записи в имени файла в разных частях входного файла - занимает немного работы.

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

После того как вы определили логику, фактический сценарий не слишком сложный. В то время как есть, вероятно, много других способов сделать это, вот один из способов, чтобы удовлетворить ваши требования:

Добавление строк из нескольких файлов

#!/bin/bash 

tfn='sqlfname.tmp' ## tmp file to track filenames created across multiple files 

while read -r line; do 

    if [ $(expr "$line" : "^use[ ].*$") -gt 0 ]; then ## begins with 'use' 
     fname=$(expr "$line" : "^use[ ]\(.*\)[;]$") ## filename after 'use' 
     if [ ! -f "$tfn" ]; then ## if tmp file does not exist create 
      :> "$fname" 
      echo " creating $fname" 
      echo "$fname" >> "$tfn" 
      continue 
     fi 
     if ! grep -q "$fname" "$tfn" ; then ## check if filename in tmp file 
      :> "$fname" 
      echo " creating $fname" 
      echo "$fname" >> "$tfn" 
     fi 
     continue 
    fi 

    echo " $line --> $fname" ## output to terminal (debug info) 
    echo "$line" >> "$fname" ## output to "$fname" 

done < "$1" 

exit 0 

Супер простая версия ж/Нет Revision Control

Кроме того, если вам не нужно отслеживать, какие файлы были созданы, и вы будете будет ответственным за удаление/сброс файлов TestX, если это необходимо, затем вы можете использовать очень упрощенную версию.

Единственный недостаток здесь заключается в том, что все файлы TestX не могут начаться в определенный момент времени. Это может быть совершенно нормально для вас, но причина для отслеживания файлов в первую очередь заключалась в том, чтобы гарантировать известную отправную точку для содержимого в каждом файле.

С точки зрения сценария, по крайней мере без гарантии того, что последовательной точки во времени, ответственность ложится на пользователя (вы), чтобы удалить все файлы TestX перед началом окончательного разбора всех SQL-файлов для их создания. Но..он делает сценарий очень простой :)

#!/bin/bash 

while read -r line; do 

    if [ $(expr "$line" : "^use[ ].*$") -gt 0 ]; then ## begins with 'use' 
     fname=$(expr "$line" : "^use[ ]\(.*\)[;]$") ## filename after 'use' 
     continue 
    fi 

    echo " $line --> $fname" ## output to terminal (debug info) 
    echo "$line" >> "$fname" ## output to "$fname" 

done < "$1" 

exit 0 

Входной

$ cat dat/sqlcreate.txt 
use Test1; 
aaaa 
bbb 
ccc 
use Test2; 
zzzz 
dddd 
use Test3; 
jjj 
use Test1; 
kkk 
lll 

Выход

$ bash parsecreatesql.sh dat/sqlcreate.txt 
    creating Test1 
    aaaa --> Test1 
    bbb --> Test1 
    ccc --> Test1 
    creating Test2 
    zzzz --> Test2 
    dddd --> Test2 
    creating Test3 
    jjj --> Test3 
    kkk --> Test1 
    lll --> Test1 

Файлы Создано/Content

$ printf "\nTest1\n"; cat Test1; printf "\nTest2\n"; \ 
cat Test2; printf "\nTest3\n"; cat Test3 

Test1 
aaaa 
bbb 
ccc 
kkk 
lll 

Test2 
zzzz 
dddd 

Test3 
jjj 

Сообщите мне, если у вас есть вопросы. Исходная версия перемещается ниже, если вам все равно придется рисовать.

Добавление строк из одного файла (оригинальное)

#!/bin/bash 

declare -a created  ## array to track filenames created 

while read -r line; do 

    # if [ "${line%% *}" = "use" ]; then  ## test begins with 'use' 
    if [ $(expr "$line" : "^use[ ].*$") -gt 0 ]; then 
     # fname=${line##* } 
     # fname=${fname%;}     ## parse filename after 'use' 
     fname=$(expr "$line" : "^use[ ]\(.*\)[;]$") 
     entries=${#created[@]}    ## check number files created 
     if [ "$entries" -eq 0 ]; then  ## if 0, truncate add to array 
      :> "$fname" 
      echo " creating $fname" 
      created+=("$fname") 
      continue 
     else ## check all filenames in array 
      for ((i = 0; i < entries; i++)) do 
       [ "${created[i]}" = "$fname" ] && break ## already created, skip 
       if [ "$i" -eq $((entries - 1)) ]; then ## if not, create 
        :> "$fname" 
        echo " creating $fname" 
        created+=("$fname") 
       fi 
      done 
      continue 
     fi 
    fi 

    echo " $line --> $fname" ## output to terminal (debug info) 
    echo "$line" >> "$fname" ## output to "$fname" 

done < "$1" 

exit 0 
+0

Благодарности это работает как шарм, но одна проблема с этим .. этот сценарий будет Grep для любого «использовать» строки во всех line У меня есть небольшое условие, которое мы должны добавить здесь. if ["$ {line %% *}" = "use"]; то можем ли мы что-то изменить, если ["$ {line %% *}" = "^ use"]; затем используя эту крышку «^ используйте» только grep для линии, начинающейся с использования. Таким образом, код wiil не сломается, можете ли вы помочь на том же – sai

+0

Итак, вы хотите привязать 'use' к началу строки. Вы можете изменить тип теста на 'if [$ (expr" $ line ":"^use []. * $ ") -Gt 0]' Я обновлю скрипт. –

+0

Я также заменил встроенные выражения для синтаксического анализа 'fname' с помощью регулярного выражения' fname = $ (expr "$ line": "^ use [] \ (. * \) [;] $") ', Что эквивалентно. Единственный недостаток 'expr' - это немного медленнее, чем встроенные, но для небольших заданий (менее 100 000 строк это не так уж плохо). Я оставил оригинальные встроенные комментарии. Выбирайте. Если вы имеете дело с именами файлов, которые потенциально имеют пробелы, вы должны удвоить котировку всей подстановки команды (например, 'fname =" $ (expr ...) "' –

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