サンプルファイルを入手するには:

サンプルファイルを入手するには:

I Chingの64個のヘキサグラムに基づいて、64個の等しくない部分に分割したいテキストファイルがあります。各六角形の段落は数字、ピリオド、2つの改行で始まり、正規表現を書くのは簡単です。

しかし、この正規表現に基づいて実際にテキストファイルを64の新しいファイルに分割するにはどうすればよいですか?これは仕事のように見えますperl。しかし、たぶん私が完全に見逃しているより明確な方法があるかもしれません。

答え1

例外は、正規csplit表現が1行でなければならないということです。これはまた状況をsed困難にする。私はPerlまたはPythonを選択します。

あなたは見ることができます

csplit foo.txt '/^[0-9][0-9]*\.$/' '{64}'

あなたの目的に十分です。 (POSIX BREが必要なため、背中とcsplit一緒に使用することはできません。)\d+

答え2

私の考えの最良の方法はとawkですgawk

アッ

awk -F "([.] )|( / )" '/^[0-9]{1,3}[.]/{x="F"$1"("$2").txt";}{print >x;}' I_Ching_Wilhelm_Translation.txt

-F各行にフィールド区切り文字が割り当てられます。これは正規表現であり、ここでは複数の区切り文字". "とを使用します" / "。したがって、このような行は1. Ch'ien / The Creative3つのフィールドに分割されます。後でこれを使用してこれらのフィールドを参照できます。フルラインです。1 Ch'ienThe Creative$n$0

次に、awkに行をパターンと一致させるように指示します。 ^[0-9]{1,3}[.]一致するものがあれば、値をに割り当てますx。 x値はprintジョブのファイル名として使用されます。この例では、"F"$1"("$2").txt"so 行を使用して1. Ch'ien / The Creativeファイル名を指定します。F1(Ch'ien).txt

愚かな

gawkでは、キャプチャされたグループにアクセスすることもできます。したがって、コマンドは次のように単純化できます。

gawk 'match($0, /^([0-9]{1,3})[.] (.*) \/ (.*)$/, ary){x="F"ary[1]"("ary[2]")";}{print >x;}' I_Ching_Wilhelm_Translation.txt

ここでは、matchキャプチャグループを使用して変数のリストに入れますary$0フルラインです。ary[0]すべてが一致します。ary[1...n]各グループです。

真珠

Perlを使用してこれを行うこともできます。

perl -ne 'if(/^([0-9]{1,3})[.] (.*) \/ (.*)$/) {close F; open F, ">", sprintf("F$1($2).txt");} print F' I_Ching_Wilhelm_Translation.txt

結果:

> ls F*
F10(Lü).txt         F22(Pi).txt       F34(Ta Chuang).txt  F46(Shêng).txt     F58(Tui).txt
F11(T'ai).txt       F23(Po).txt       F35(Chin).txt       F47(K'un).txt      F59(Huan).txt
F12(P'i).txt        F24(Fu).txt       F36(Ming I).txt     F48(Ching).txt     F5(Hsü).txt
F13(T'ung Jên).txt  F25(Wu Wang).txt  F37(Chia Jên).txt   F49(Ko).txt        F60(Chieh).txt
F14(Ta Yu).txt      F26(Ta Ch'u).txt  F38(K'uei).txt      F4(Mêng).txt       F61(Chung Fu).txt
F15(Ch'ien).txt     F27(I).txt        F39(Chien).txt      F50(Ting).txt      F62(Hsiao Kuo).txt
F16(Yü).txt         F28(Ta Kuo).txt   F3(Chun).txt        F51(Chên).txt      F63(Chi Chi).txt
F17(Sui).txt        F29(K'an).txt     F40(Hsieh).txt      F52(Kên).txt       F64(Wei Chi).txt
F18(Ku).txt         F2(K'un).txt      F41(Sun).txt        F53(Chien).txt     F6(Sung).txt
F19(Lin).txt        F30(Li).txt       F42(I).txt          F54(Kuei Mei).txt  F7(Shih).txt
F1(Ch'ien).txt      F31(Hsien).txt    F43(Kuai).txt       F55(Fêng).txt      F8(Pi).txt
F20(Kuan).txt       F32(Hêng).txt     F44(Kou).txt        F56(Lü).txt        F9(Hsiao Ch'u).txt
F21(Shih Ho).txt    F33(TUN).txt      F45(Ts'ui).txt      F57(Sun).txt

サンプルファイルを入手するには:

curl http://www2.unipr.it/~deyoung/I_Ching_Wilhelm_Translation.html|html2text -o I_Ching_Wilhelm_Translation.plain
sed 's|^[[:blank:]]*||g' I_Ching_Wilhelm_Translation.plain > I_Ching_Wilhelm_Translation.txt

答え3

csplitGNU coreutilsを使用すると、ファイルを正規表現で区切られたフラグメントに分割できます。オタクドラゴンが見せたように

これは、ファイルをさまざまな部分に分割するための移植可能なawkスクリプトです。仕組みは次のとおりです。

  • getline複数行(2行)区切り文字を処理するために呼び出されます。
  • outfileセクションヘッダーが表示されたら、変数を印刷するファイル名に設定します。
BEGIN {outfile="header.txt"}
{
    while (/^[0-9]+\.$/) {
        prev = $0; getline;
        if ($0 == "") outfile = prev "txt";
        print prev >outfile
    }
    print >outfile
}

答え4

分割の理由が別のコマンドで各チャンクを処理することである場合、GNU Parallelは選択ツールです。

cat I_Ching_Wilhelm_Translation.txt |
  parallel -N1 --pipe --regexp --recend '\n' --recstart '[0-9]{1,3}[.] [^\n]+ /' 'cat > {#}'

cat > {#}これは実行コマンドに置き換えることができます。

関連情報