シェルスクリプトを使用して行テキストに基づいて.txtファイルを3つのファイルに分割する

シェルスクリプトを使用して行テキストに基づいて.txtファイルを3つのファイルに分割する

ツール出力から.txtファイルをインポートする必要があります。これを3つに分割したいと思います。

ファイルのテキストの例:

First line
Second line
23456
45677
45678

Third line
90909
90678

Last line
Z567Z
6787T

予想出力:

->ファイル1.txt

23456
45677
45678

->ファイル2.txt

90909
90678

- >ファイル3.txt

Z567Z
5677T

デフォルトでは、ファイルには使用したい5桁の数字/英数字の値があり、その間のテキストはファイルを複数のファイルに分割するための識別子として使用されます。

awkこれを行うには、orコマンドを使用しようとしますsed

答え1

これが必要なものではない場合:

$ awk '
    /^[[:alnum:]]{5}$/ {
        if ( !inBlock++ ) {
            close(out)
            out = "file" (++cnt) ".txt"
        }
        print > out
        next
    }
    { inBlock = 0 }
' file

$ head file?.txt
==> file1.txt <==
23456
45677
45678

==> file2.txt <==
90909
90678

==> file3.txt <==
Z567Z
6787T

次に、質問を編集して、より明確な要件とより代表的な入力/出力の例を提供します。

答え2

これは醜いラインです。

grep -v '[:alpha:]' test.txt | sed "s/^$/==/g" | split -p "=="

注:これにより、「==」パターンに基づいて3つ以上のファイル(xa *)が生成されます。

さらに、 for ループを使用して "==" (sed 's/=//g' xa* | grep -v "^$") (存在する場合) を削除できます。

答え3

GNU ツールボックスで grep+csplit を使用できます。

grep -v '\W' < your_file |
csplit --suppress-matched \
  -szn1 -f file -b '%d.txt' \
  - '/^$/' '{*}'

awk は短絡モードにあり、レコードは少なくとも 1 つの空行で区切られます。

awk -v RS= '
match($0,/\n[[:alnum:]]+(\n|$)/) {
  out = "file" NR ".txt"
  print substr($0,1+RSTART) > out
  close(out)
}
' your_file

GNU sedを使用して最初に入力データからsedコードを生成し、それを操作して必要な出力ファイルを生成します。

sed -En '
  1{x;s/.*/123/;x;}
  /^\w+$/{=;$z;}
  /^$/{
    G
    s/^(.)(.)(.*)/wfile\2.txt\1\3/
    P;s/.*\n//;h
  }
' your_file | sed -Ee '
  :a;N;/\n[0-9]+$/ba
  s/\n(.*\n)?([0-9])/,\2/
  s/\n//
' - | sed -nf - your_file

出力ファイル:csplitの場合、ファイル番号の指定は0から始まります。

==> file1.txt <==
23456
45677
45678

==> file2.txt <==
90909
90678

==> file3.txt <==
Z567Z
6787T

関連情報