
次の形式のパイプで区切られたファイルがあります。
1|ABC|11|DEF|111
2|ABC|22|PQR
ST
UW|222
3|ABC|33|XYZ|333
4|ABC|44|LMN|444
2
このレコードをテーブルに挿入しようとしたときから始まる行の場合、レコードのみが挿入され、開始行からレコードの挿入が開始されPQR
ます。4
テーブルに行2を正常に挿入するのに役立つすべての行2レコードを単一の行に入れるコマンドがある場合は、ありがとうございます。
答え1
レコードに含まれる改行文字をスペースに置き換えるには、GNUを使用しますawk
。
num_fields=4
awk -v RS='([^|]*\\|){'"$num_fields"'}[^|]*\n' '
{
n = split(RT, a,"|");
for (i=1; i<=n; ++i)
{
gsub("\n", " ", a[i]);
printf "%s%s", a[i], i==n?"\n":"|"
}
}' file
これは
1|ABC|11|DEF|111
2|ABC|22|PQR ST UW|222
3|ABC|33|XYZ|333
4|ABC|44|LMN|444
ここでの秘密は、awk
任意のレコード区切り文字のGNUサポートを使用して1つを4つのパイプ終了フィールドと改行終了フィールドとして定義し、すべてのフィールドに埋め込まれたパイプをRS='([^|]*\\|){4}[^|]*\n'
含めることを許可しないことです。 。
この仕様に準拠した実際のレコード区切り文字は、を通じてアクセスできますRT
。RT
パイプを介して配列に分割しa
、各要素に含まれている改行文字を削除しa
、最後に要素を再結合してレコードを書き換えるだけの簡単な問題です。a
答え2
このクレイジーファイル形式からフラグメントを抽出する1つの方法はPerlを使用することです。
#!/usr/bin/perl
#
use warnings;
use strict;
undef $/;
my $file = <>;
while ($file =~ /^(.*?\|.*?\|.*?\|.*?\|.*?)$/mscg) {
my $fields = $1;
$fields =~ s/\n(.)/\\n$1/sg;
print "$fields\n";
}
コードはファイル全体をメモリに入れ、|
1行に5つの区切りフィールドに再度チャンクします。含まれる改行文字は\n
。
スクリプトが呼び出されたら、それをrepipe.pl
使用してdatafile
。perl repipe.pl datafile
問題がある場合は、次のように1行で含めることができますが、メンテナンスには大きな助けにはなりません。
perl -e 'undef $/; $file = <>; while ($file =~ /^(.*?\|.*?\|.*?\|.*?\|.*?)$/mscg) { $fields = $1; $fields =~ s/\n(.)/\\n$1/sg; print "$fields\n"; }' datafile
以下は、サンプルデータファイルの出力です。
1|ABC|11|DEF|111
2|ABC|22|PQR\nST\nUW|222
3|ABC|33|XYZ|333
4|ABC|44|LMN|444