1

テキスト ファイルがあり、行の内容を 1 行にまとめたいと考えています。例えば。

という名前のテキスト ファイルがあり、次の内容WEEE.txtが含まれています。

BSS100  PROF  K


BSS101  TREES E
BSS102  TRUNK R, S,
              V, R,
              T
BSS103  TEXT  KE
BSS104  WEEW  KER,
              SSS

次のような出力が必要です。

BSS100  PROF  K
BSS101  TREES E
BSS102  TRUNK R, S, V, R, T
BSS103  TEXT  KE
BSS104  WEEW  KER, SSS

しかしねえ。これは、私が現在行っているプロジェクトの一部です。これが本物です!例として一番上に最初のものを挙げますが、できません。:) 私を助けてください!(おそらくこれは BSC.txt です)

BSC195






PROFILE             VDU0 , VDU1 , VDU2 , VDU3 , VDU4 , VDU5 ,
                    VDU6 , VDU7 , VDU8 , VDU9 , VDU10, VDU11,
                    VDU12, VDU13, VDU14, VDU15, CAL0 , VTP
MOKAS               NOKIA1
CBCERTCK            D10393
NUTRDM              NUPADM
SPMNGT              SPMNGT
NFTRA
RCCFVS              RCCMLA
TRAFAD              TRAFAD
NOCORF              NOCOSS
NETWCH              NETWCH
BSCOP5              BSCOPT
MMOPTI              MMOPTI
SYSSDE              SYSOP1
SMCSOC              SMCSOC
LRCCMM              ITNCCM
VENFVD              VENNSN
BSCGBF              BSCRHM
BSHGTD              BSCLOC, P10203
BSCASD              BSCEMR
LSCRIPT
BSCGVS              A13728, J02448, L13668, M14730, A12868, C11347,
                    L14203, C02285, A14419, B00797, S12666, M12653,
                    D04841, S02825, T14713, L15004, C01972, E12057,
                    S13319
LSNCMM              F02642
LSYSCRIPT           CATSYS

これは私がしたいことです:

BSC195






PROFILE             VDU0 , VDU1 , VDU2 , VDU3 , VDU4 , VDU5 ,VDU6 , VDU7 , VDU8 , VDU9 , VDU10, VDU11, VDU12, VDU13, VDU14, VDU15, CAL0 , VTP *
MOKAS               NOKIA1
CBCERTCK            D10393
NUTRDM              NUPADM
SPMNGT              SPMNGT
NFTRA
RCCFVS              RCCMLA
TRAFAD              TRAFAD
NOCORF              NOCOSS
NETWCH              NETWCH
BSCOP5              BSCOPT
MMOPTI              MMOPTI
SYSSDE              SYSOP1
SMCSOC              SMCSOC
LRCCMM              ITNCCM
VENFVD              VENNSN
BSCGBF              BSCRHM
BSHGTD              BSCLOC, P10203
BSCASD              BSCEMR
LSCRIPT
BSCGVS              A13728, J02448, L13668, M14730, A12868, C1198, L14203, C02285, A14419, B00797, S12666, M12653,D04841, S02825, T14713, L15004, C01972, E12057, S13319 *
LSNCMM              F02642
LSYSCRIPT           CATSYS

注: * は、1 行にまとめたいという意味です。BSCGVS から S133319 までを 1 行で。VTP までの PROFILE と同様に。まだ可能ですか?別の注意: これは私のデータのほんの一部です。助けてください。どうすればいいのかわからない。これは私のデータベースへの入力になるからです。=) 助けてください =)

4

5 に答える 5

5
sed ':a; N;/\n\S/! {s/\n */ /;ba}; P;D' WEEE.txt
于 2013-05-08T07:46:09.857 に答える
1
awk '/^\S/{printf "%s%s",rs,$0; rs="\n"; next} {$1=" "$1;printf "%s",$0} END{print ""}' file

入力ファイルが BS で始まる行で終わっている場合と終わっていない場合に試してください。

$ cat file
BSS100  PROF  K
BSS101  TREES E
BSS102  TRUNK R, S,
              V, R,
              T
BSS103  TEXT  KE
BSS104  WEEW  KER,
              SSS
$
$ awk '/^\S/{printf "%s%s",rs,$0; rs="\n"; next} {$1=" "$1;printf "%s",$0} END{print ""}' file
BSS100  PROF  K
BSS101  TREES E
BSS102  TRUNK R, S, V, R, T
BSS103  TEXT  KE
BSS104  WEEW  KER, SSS
$
$ cat file1
BSS100  PROF  K
BSS101  TREES E
BSS102  TRUNK R, S,
              V, R,
              T
BSS103  TEXT  KE
BSS104  WEEW  KER,
              SSS
BSS104  WEEW  FOO
$
$ awk '/^\S/{printf "%s%s",rs,$0; rs="\n"; next} {$1=" "$1;printf "%s",$0} END{print ""}' file1
BSS100  PROF  K
BSS101  TREES E
BSS102  TRUNK R, S, V, R, T
BSS103  TEXT  KE
BSS104  WEEW  KER, SSS
BSS104  WEEW  FOO
于 2013-05-08T16:48:22.457 に答える
1

UPDATED#2 と改善ソリューションを過度に複雑にしました。簡略化したものはこちら

純粋な解決策が必要な場合はbash、上記のスクリプトを試してください。内部bash関数のみを使用するため、外部プログラムは呼び出されません (まったくありませんfork)。

while read; do
  #Skip empty lines
  [[ $REPLY =~ ^[[:space:]]*$ ]] && continue
  # Chomp all but one leading spaces
  [[ $REPLY =~ ^[[:space:]]+(.*) ]] && REPLY=" ${BASH_REMATCH[1]}"
  # Chomp trailing spaces
  [[ $REPLY =~ (.*[^[:space:]])[[:space:]]+$ ]] && REPLY="${BASH_REMATCH[1]}"
  echo -e "$REPLY\c"
  # Add LF at the end if not finished with ','
  [[ $REPLY =~ ,$ ]] || echo
done <<XXX
BSS100  PROF  K



BSS101  TREES E
BSS102  TRUNK R, S, 
              V, R,
              T
BSS103  TEXT  KE
BSS104  WEEW  KER,
              SSS
XXX

出力:

BSS100  PROF  K
BSS101  TREES E
BSS102  TRUNK R, S, V, R, T
BSS103  TEXT  KE
BSS104  WEEW  KER, SSS

とは:

最初に、ファイルは while ループにリダイレクトされます。cat file|while二重にしないので、一般的に使用されるよりも優れていますfork(1 つはループの実行cat用で、もう 1 つbashはループの実行用while)。ここでは、「ここにあるドキュメント」機能を使用して、より妥当な例を作成しました。ただし、while ... done <filenameフォームも使用できます。

  • whileループは、ファイルのすべての行を処理します。それ以上の引数がない場合はread、読み取り行をREPLYenv var に配置します。
  • 次にREPLY、ゼロまたはそれ以上の空白文字 (スペースまたはタブ) が (のみ) 含まれているかどうかがチェックされます。もしそうなら、ループは続きました。
  • 次にREPLY、1 つ以上の空白で始まるかどうかがチェックされます。その場合、複数の空白が 1 つの空白文字に置き換えられます。
  • 次にREPLY、1 つ以上の空白で終わるかどうかがチェックされます。その場合、複数の空白は削除されます。
  • その後REPLY、改行なしで印刷されます。
  • 次にREPLY、で終わるかどうかがチェックされます,。そうでない場合、改行はプリンターです。

    参考文献: bash(1) , regex(7) , fork(2)

  • 于 2013-05-08T10:42:56.863 に答える
    0

    私は得意ではありませんawkが、とにかく:

    >awk '/^BSS/ {if (NR>1) printf("\n"); printf("%s", $0);} !/^BSS/ {printf(", %s", $1); } END {printf("\n");} ' WEEE.txt
    BSS100   K
    BSS101   E
    BSS102   R, V, S
    BSS103   KE
    BSS104   KER, SSS
    

    アップデート

    >awk '/^BSS/ {if (NR>1) printf("\n"); for(i=3;i<=NF;i++) gsub(",$", "", $i);  printf("%s %s %s", $1, $2, $3);  for(i=4;i<=NF;i++) printf(", %s", $i); } !/^BSS/ { for(i=1;i<=NF;i++) {gsub(",$", "", $i); printf(", %s", $i);}  }END {printf("\n");}  ' WEEE.txt
    BSS100 PROF K
    BSS101 TREES E
    BSS102 TRUNK R, S, V, R, T
    BSS103 TEXT KE
    BSS104 WEEW KER, SSS
    
    于 2013-05-08T07:57:50.077 に答える