Yi Jing의 64 hexagrams에 따라 64 개의 동일하지 않은 부분으로 분할하려는 텍스트 파일이 있습니다. 각 hexagram에 대한 구절은 일부 숫자, 마침표 및 두 줄 바꿈으로 시작하므로 정규식을 작성하기가 매우 쉽습니다.
그러나이 정규식에 따라 실제로 텍스트 파일을 64 개의 새 파일로 어떻게 분할합니까? 에 대한 더 많은 작업처럼 보입니다 perl
. 그러나 내가 완전히 놓친 더 분명한 방법이있을 수 있습니다.
답변
이것은 csplit
정규 표현식 이 한 줄이어야 한다는 것을 제외하고는 것입니다. 그것은 또한 sed
어렵다. 나는 Perl이나 Python과 함께 갈 것이다.
당신은 볼 수 있습니다
csplit foo.txt '/^[0-9][0-9]*\.$/' '{64}'
당신의 목적에 충분합니다. ( csplit
이 사용할 수 있도록 POSIX BRE는 필요 \d
또는 +
다른 사람의 사이에서.)
답변
가장 좋은 방법은 awk
과 gawk
입니다.
어 wk
awk -F "([.] )|( / )" '/^[0-9]{1,3}[.]/{x="F"$1"("$2").txt";}{print >x;}' I_Ching_Wilhelm_Translation.txt
-F
각 줄에 대해 필드 구분 기호를 지정합니다. 그것은 정규식, 우리가 여러 seperators를 사용 ". "
하고 " / "
. 따라서 같은 줄 1. Ch'ien / The Creative
은 3 개의 필드로 나뉩니다 : 1
Ch'ien
및 The Creative
. 나중에이 필드를로 참조 할 수 있습니다 $n
. $0
전체 라인입니다.
그런 다음 awk에게 패턴과 라인을 일치 시키 ^[0-9]{1,3}[.]
라고 지시 x
합니다. x 값은 print
조작을 위한 파일 이름으로 사용됩니다 . 이 예제에서 우리 "F"$1"("$2").txt"
는 라인 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 -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
답변
GNU coreutils를 사용 csplit
하면 geekosaur가 보여주는 것처럼 파일을 정규 표현식으로 구분 된 조각 으로 나눌 수 있습니다 있습니다.
다음은 파일을 여러 조각으로 나누는 이식 가능한 awk 스크립트입니다. 그것은에 의해 작동
- 여러
getline
줄 (2 줄) 구분 기호를 처리하기 위해 호출 ; outfile
섹션 헤더가 발견 될 때 인쇄 할 파일 이름으로 변수 를 설정합니다 .
BEGIN {outfile="header.txt"}
{
while (/^[0-9]+\.$/) {
prev = $0; getline;
if ($0 == "") outfile = prev "txt";
print prev >outfile
}
print >outfile
}