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

注意:* 表示我希望它在一行中。从 BSCGVS 到 S133319 在一条线上。以及在高达 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 '/^BS/{printf "%s%s ",s,$0;s="\n";next}{sub(/^\s*/,"");printf "%s ",$0}' file
BSS100  PROF  K
BSS101  TREES E
BSS102  TRUNK R, S, V, R, T
BSS103  TEXT  KE
BSS104  WEEW  KER, SSS
于 2013-05-08T11:44:55.187 回答
1

UPDATED#2 和 IMPROVED我使解决方案过于复杂。这是简化的

如果您需要纯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(一个用于运行循环cat,一个用于bash运行while循环)。在这里,我使用“here-is-the-document”功能来制作更合理的示例。但是您也可以使用该while ... done <filename表格。

  • 循环处理文件中的while所有行。如果没有进一步的参数,read它将读取行放置到REPLYenv var。
  • 然后REPLY检查它是否包含(仅)零个或多个空白字符(空格或制表符)。如果是这样,则循环继续。
  • 然后REPLY检查它是否以一个或多个空格开头。如果是这样,则多个空格替换为一个空格字符。
  • 然后REPLY检查它是否以一个或多个空格结尾。如果是这样,则消除了多个空格。
  • 然后REPLY在没有换行的情况下打印。
  • 然后REPLY检查它是否以,. 如果不是这样,那么换行符就是打印机。

    参考:bash(1)regex(7)fork(2)

  • 于 2013-05-08T10:42:56.863 回答
    1
    awk '/^\S/{printf "%s%s",rs,$0; rs="\n"; next} {$1=" "$1;printf "%s",$0} END{print ""}' file
    

    当您的输入文件以 BS 开头的行结束并且不以 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 回答
    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 回答