web-dev-qa-db-ja.com

ファイルから複数のセクション/行を分離する

以下のサンプルテキストを含むファイルがあります。

THIS(
is first
Line);
THAT(
is second line);
THIS(
is third
line);
THAT(
is 
fourth
line);

ファイルが表示されている場合、各セクションは「THIS」または「THAT」で始まり、テキストの各セクションはセミコロン(;)。 「THIS」と「THAT」の両方を検索し、すべての「THIS」セクションをファイルにコピーするUnixコマンド/スクリプトが必要ですfirst_file、およびすべての「THAT」セクションを別のファイルにsecond_file

例:最初のファイルには次のものが含まれている必要があります。

THIS(
is first
Line);
THIS(
is third
line);

2番目のファイルには次のものが含まれている必要があります。

THAT(
is second line);
THAT(
is 
fourth
line);
1
dev

与えられた

$ cat thisthat 
THIS(
is first
Line);
THAT(
is second line);
THIS(
is third
line);
THAT(
is 
fourth
line);

その後

awk -vRS=';\n' 'BEGIN{ORS=RS} /^THIS/ {print > "these"} /^THAT/ {print > "those"}' thisthat

結果

$ head these those 
==> these <==
THIS(
is first
Line);
THIS(
is third
line);

==> those <==
THAT(
is second line);
THAT(
is 
fourth
line);
3
steeldriver

任意のawkで:

$ awk -v RS=';' 'NF{sub(/^\n/,""); print > (/^THIS/ ? "first_file" : "second_file")}' file

$ cat first_file
THIS(
is first
Line)
THIS(
is third
line)

$ cat second_file
THAT(
is second line)
THAT(
is
fourth
line)

またはGNUマルチチャーRSおよびRTの場合はawk:

$ awk -v RS='(THIS|THAT)[^;]+;\n' -v ORS= '{$0=RT; print > (/^THIS/ ? "first_file" : "second_file")}' file

$ cat first_file
THIS(
is first
Line);
THIS(
is third
line);

$ cat second_file
THAT(
is second line);
THAT(
is
fourth
line);

どちらのソリューションも、例が正確であり、ブロックの最後を除いて;sがないことを前提としています(たとえば、(...)パーツ内にない)。

1
Ed Morton

edファイルエディタを使用しますが、2番目の(空の)ファイルを事前に作成する必要があります。この例では、元のファイルの名前はfile1です。

file2という名前の2番目のファイルを作成します

> file2

ヒアドキュメント

ed -s file1 << 'EOF'
H
g/^THAT($/;/^.*\;$/d
w
u
g/^THIS($/;/^.*\;$/d
0r file2
w file2
EOF

ヒアドキュメントfile1を使用してed -s file1 << 'EOF'edにフィードする最初の行

2行目は、エラーに役立つより詳細なメッセージを出力します。 H

3行目THAT(で始まる行を;で終わる行まで削除します。

g/^THAT($/;/^.*\;$/d

4行目変更をfile1に書き込みますw

5行目ファイル1ではなくバッファでのみ変更を元に戻します。 u

6行目THIS(で始まる行を;で終わる行まで削除します。

g/^THIS($/;/^.*\;$/d

7行目バッファ内の残りのテキストをfile2の先頭に追加します

0r file2

8行変更ファイルを書き込みます2。 w file2


ワンライナー。

>file2; printf '%s\n' H 'g/^THAT($/;/^.*\;$/d' w u 'g/^THIS($/;/^.*\;$/d' '0r file2' 'w file2' | ed -s file1

edはファイルを編集しますin-placeは、ファイルが直接編集され、出力が他の場所に出力されないことを意味します。そのため、edを実行する前に、まずいくつかの例でテストしてください。プロダクションファイル。

0
Jetchisel

AwkFlagメソッドで試してみました

awk '/THIS/{f=1}/THAT/{f=0}f' file > file1(Contains "THIS" PATTERN)
awk '/THAT/{f=1}/THIS/{f=0}f' file > file2(Contains "THAT" PATTERN)

出力

cat file1

THIS(
is first
Line);
THIS(
is third
line);



cat file2

    THAT(
    is second line);
    THAT(
    is 
    fourth
    line);
0