使用shell脚本解析文件

时间:2015-10-17 05:41:39

标签: shell

[root@localhost sql]# cat a.sql 
use Test1;
aaaa
bbb
ccc
use Test2;
zzzz
dddd
use Test3;
jjj
use Test1;
kkk
lll

大家好我想用下面的方式解析about文件,我需要使用shell脚本,任何人都可以帮我编写脚本。 从文件中它必须创建一个基于^ use的单独文件并继续追加下一行,直到再使用一次,所以我需要的最终输出是

1)需要创建三个文件

  

Test1 Test2 Test3

2)如果我接受Test1,Test2和Test3

$ cat Test1
aaaa
bbb
ccc
kkk
lll


$ cat Test2
zzzz
dddd


$ cat Test3
jjj

请帮助我:-(

1 个答案:

答案 0 :(得分:1)

虽然这一开始可能看起来很简单,但是要正确地执行它并处理现有文件的初始测试,如果文件存在则截断,并且还要在输入文件的不同部分处理文件名的重复条目 - 需要一些工作

您需要跟踪脚本到目前为止创建的文件名,如果再次看到同一文件,则需要继续追加该文件,而不是截断并开始新文件。

一旦你整理了逻辑,实际的脚本就不会太难了。虽然可能有很多其他方法可以做到这一点,但这是满足您要求的一种方法:

从多个文件添加行

#!/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

超级简单版本没有版本控制

此外,如果您不关心跟踪已创建的文件,将负责删除/重置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

创建的文件/内容

$ 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