Top > シェルあれこれ > 階層のあるディレクトリを走査

Everything is expanded.Everything is shortened.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
 
 
 
-
|
|
|
|
|
|
|
|
|
|
|
|
-
|
|
-
|
-
|
!
|
!
!
 
 
 
 
 
 
 
 
-
|
|
|
|
|
|
-
|
-
|
-
|
!
|
!
-
|
!
|
!
 
 
 
 
 
 
 
 
-
|
!
 
 
 
 
 
 
 
 
-
|
-
|
-
|
!
-
|
|
!
|
!
|
|
|
!
 
 
 
 
 
 
 
 
-
|
|
|
|
|
|
-
|
-
-
|
|
!
-
|
!
!
|
|
!
 
-
|
|
-
|
|
!
|
!
 
 
 
 
 
 
-
|
|
|
|
|
|
|
|
|
|
|
-
|
!
|
!
 
 
 
 
 
 
 
 
 
-
|
|
|
|
|
|
-
|
-
|
-
|
!
|
!
|
!
 
 
 
 
 
 
 
 
-
|
!
 
 
 
 
 
 
 
 
-
|
|
|
|
|
|
-
|
-
-
|
|
!
-
|
!
!
|
|
!
 
 
#!/bin/sh
 
gawk -f- << "END_OF_FILE" okinawa.csv
{
    printf("Row : %d %s\n", NR, $0);
 
    #検索開始位置。gawkは[1]オリジンです。
    source_infs["curPos"] = 1;
 
    #処理対象文字列
    source_infs["source"] = buffer $0;
 
    source_infs["srcLen"] = length(source_infs["source"]) + 1;
 
    #データ内に改行が含まれるデータかチェックします。
    immature = isImmatureData(source_infs);
    if( immature ) {
        #改行があった場合、グローバルな領域に退避します。
        buffer =  source_infs["source"] "\n";
    } else {
        #一要素ずつ表示します。
        while(hasMoreTokens(source_infs)) {
            printf("[%s]\n", nextToken(source_infs));
        }
        buffer = "";
    }
}
 
#######################################################
# 次のカンマがある位置を返す。
# @param source_infs["curPos"] 検索を開始する位置
# @param source_infs["srcLen"] CSVデータ長
# @param source_infs["source"] CSVデータ
# @return 次のカンマがある位置
#######################################################
function getNextCommaPos(source_infs) {
 
    curPos = source_infs["curPos"];
    srcLen = source_infs["srcLen"];
    source = source_infs["source"];
 
    inner_env = 0;
    while (curPos < srcLen) {
        ch = substr( source, curPos, 1 );
        if (inner_env == 0 && ch == ",") {
            break;
        } else if ("\"" == ch) {
            inner_env = !inner_env;
        }
        curPos++;
    }
    if( inner_env == 1 ) {
        curPos = -1;
    }
    return curPos;
}
 
#######################################################
# まだ項目が残っているか?
# @param source_infs["curPos"] 検索を開始する位置
# @param source_infs["srcLen"] CSVデータ長
# @param source_infs["source"] CSVデータ
# @return 残っている:true 残っていない:false
#######################################################
function hasMoreTokens(source_infs) {
    return (getNextCommaPos(source_infs) <= source_infs["srcLen"]);
}
 
#######################################################
# データ内に改行があるか?
# @param source_infs["curPos"] 検索を開始する位置
# @param source_infs["srcLen"] CSVデータ長
# @param source_infs["source"] CSVデータ
# @return ある:true ない:false
#######################################################
function isImmatureData(source_infs) {
    rtn = 0;
    while (1) {
        pos = getNextCommaPos(source_infs);
        if( pos >= source_infs["srcLen"] ) {
            break;
        }
        if( pos<0 ) {
            rtn = 1;
            break;
        }
        source_infs["curPos"] = pos + 1;
    }
    #検索開始位置を先頭に戻します。
    source_infs["curPos"] = 1;
    return rtn;
}
 
#######################################################
# 次の項目の文字列を返す。
# @param source_infs["curPos"] 検索を開始する位置
# @param source_infs["srcLen"] CSVデータ長
# @param source_infs["source"] CSVデータ
# @return 次の項目
#######################################################
function nextToken(source_infs) {
    srcLen = source_infs["srcLen"];
    source = source_infs["source"];
    st = source_infs["curPos"];
    source_infs["curPos"] = getNextCommaPos(source_infs);
 
    strb = "";
    while (st < source_infs["curPos"]) {
        ch = substr( source, st++, 1 );
        if (ch == "\"") {
            if ((st < source_infs["curPos"]) && (substr( source, st, 1 ) == "\"")) {
                strb = strb ch;
                st++;
            }
        } else {
            strb = strb ch;
        }
    }
    source_infs["curPos"]++;
    return strb;
}
 
function countTokens(source_infs) {
    i = 0;
    ret = 1;
    while ((i = getNextCommaPos(source_infs)) < source_infs["srcLen"]) {
        source_infs["curPos"] = i + 1;
        ret ++;
    }
    return ret;
}
 
END_OF_FILE
 
#!/bin/sh
 
gawk -f- << "END_OF_FILE" okinawa.csv
{
    printf("Row : %d %s\n", NR, $0);
 
    #検索開始位置。gawkは[1]オリジンです。
    source_infs["curPos"] = 1;
 
    #処理対象文字列
    source_infs["source"] = $0;
 
    source_infs["srcLen"] = length($0) + 1;
 
    #一要素ずつ表示します。
    while(hasMoreTokens(source_infs)) {
        printf("[%s]\n", nextToken(source_infs));
    }
 
}
 
 
#######################################################
# 次のカンマがある位置を返す。
# @param source_infs["curPos"] 検索を開始する位置
# @param source_infs["srcLen"] CSVデータ長
# @param source_infs["source"] CSVデータ
# @return 次のカンマがある位置
#######################################################
function getNextCommaPos(source_infs) {
 
    curPos = source_infs["curPos"];
    srcLen = source_infs["srcLen"];
    source = source_infs["source"];
 
    inner_env = 0;
    while (curPos < srcLen) {
        ch = substr( source, curPos, 1 );
        if (inner_env == 0 && ch == ",") {
            break;
        } else if ("\"" == ch) {
            inner_env = !inner_env;
        }
        curPos++;
    }
    return curPos;
}
 
#######################################################
# まだ項目が残っているか?
# @param source_infs["curPos"] 検索を開始する位置
# @param source_infs["srcLen"] CSVデータ長
# @param source_infs["source"] CSVデータ
# @return 残っている:true 残っていない:false
#######################################################
function hasMoreTokens(source_infs) {
    return (getNextCommaPos(source_infs) <= source_infs["srcLen"]);
}
 
#######################################################
# 次の項目の文字列を返す。
# @param source_infs["curPos"] 検索を開始する位置
# @param source_infs["srcLen"] CSVデータ長
# @param source_infs["source"] CSVデータ
# @return 次の項目
#######################################################
function nextToken(source_infs) {
    srcLen = source_infs["srcLen"];
    source = source_infs["source"];
    st = source_infs["curPos"];
    source_infs["curPos"] = getNextCommaPos(source_infs);
 
    strb = "";
    while (st < source_infs["curPos"]) {
        ch = substr( source, st++, 1 );
        if (ch == "\"") {
            if ((st < source_infs["curPos"]) && (substr( source, st, 1 ) == "\"")) {
                strb = strb ch;
                st++;
            }
        } else {
            strb = strb ch;
        }
    }
    source_infs["curPos"]++;
    return strb;
}
 
END_OF_FILE

リロード   新規 編集 凍結解除 差分 添付 複製 名前変更   ホーム 一覧 単語検索 最終更新 バックアップ リンク元   ヘルプ   最終更新のRSS
Last-modified: 2012-08-08 (水) 23:26:29 (2923d)