简体   繁体   English

使用awk / tr / sed进行bash conditionnal getline?

[英]bash conditionnal getline with awk/tr/sed?

I'm struggling with this, i want to concatenate a group of lines into a single one line/row. 我正在努力解决这个问题,我希望将一组行连接成一行/一行。 Each line (titi/toto/tata) of my file has 2 or 3 fields separated by a ";" 我文件的每一行(titi / toto / tata)有2或3个以“;”分隔的字段 So my input is like this: 所以我的输入是这样的:

titi1
titi2 
titi3
43;75;97
1;2;87
toto1
toto2
toto3
40;50;60
tata1
tata2
tata3
4;5;2
5;3;7
2;5;9

I need this output : 我需要这个输出:

titi1;titi2;titi3;43;75;97
titi1;titi2;titi3;1;2;87
toto1;toto2;toto3;40;50;60
tata1;tata2;tata3;4;5;2
tata1;tata2;tata3;5;3;7
tata1;tata2;tata3;2;5;9

So has you can see the first 3 lines are informations (toto/tata etc...) that should be repeated for each line after that start with a number. 那么你可以看到前3行是信息(toto / tata等...),应该在数字开始后为每一行重复这些信息。

First my input had only one line with number so it was a grouping 4 by 4. so i searched in the forum had i found an example and did this with a getline like this : 首先,我的输入只有一行数字,所以它是一个4乘4的分组。所以我在论坛搜索了我找到了一个例子并用这样的getline做了这个:

awk '{getline b; getline c; getline d;printf("%s %s %s %s\n",$0,b,c,d)}'

But then i started to have 2 or even 3 lign with numbers... So i'm struggling doing a 'conditionnal' that understand that it should repeat the first 3 lign everytime it sees a lign starting with a numbers. 但后来我开始有2个甚至3个数字... ...所以我正在努力做一个“条件”,理解它应该重复前3个lign每次它看到一个从数字开始的lign。

Could you please try following. 你可以尝试一下吗?

awk '
{
  sub(/ +$/,"")
}
/^[a-zA-Z]+/{
  if(val && flag){
    val=""
  }
  val=val?val ";" $0:$0
  flag=""
  next
}
{
  flag=1
  print val ";" $0
}'  Input_file

Solution 2nd: In case your Input_file could have last line as tot etc and you want to print it too then use following. 解决方案第二:如果您的Input_file可以将最后一行作为tot等,并且您也想打印它,那么请使用以下内容。

awk '
{
  sub(/ +$/,"")
}
/^[a-zA-Z]+/{
  if(val && flag){
     val=""
  }
  val=val?val ";" $0:$0
  flag=""
  next
}
{
  flag=1
  print val ";" $0
}
END{
  if(val && !flag){
     print val
  }
}'  Input_file
$ awk -F';' 'NF>1{print s $0; p=1; next} p{s=p=""} {s=s $0 FS}' file
titi1;titi2;titi3;43;75;97
titi1;titi2;titi3;1;2;87
toto1;toto2;toto3;40;50;60
tata1;tata2;tata3;4;5;2
tata1;tata2;tata3;5;3;7
tata1;tata2;tata3;2;5;9

wrt your original script - see http://awk.freeshell.org/AllAboutGetline for why not to use getline for this (or most other situations) and how to call getline correctly on those rare occasions when it is appropriate to do so. 你的原始脚本 - 请参阅http://awk.freeshell.org/AllAboutGetline,了解为什么不在这个(或大多数其他情况)使用getline,以及如何在适当的情况下在极少数情况下正确调用getline。

You can try this awk : 你可以尝试这个awk:

awk -F';' 'NF==1{if(b){a=b=""};a=a$0FS;next}{b=1;$0=a$0}1' infile

And more understandable 而且更容易理解

awk -F ';' '
  NF==1 {
    if ( b ) {
      a = b = "" 
    }
    a = a $0 FS 
    next
  }
  {
    b = 1
    $0 = a $0
  } 1
' infile

This program should so: 该计划应如此:

awk 'f&&/^[^0-9]/{b="";f=0} /^[^0-9]/{b=b$0";"} /^[0-9]/{print b$0;f=1}'

Explanation: 说明:

  1. /^[^0-9]/{b=b$0";"}
  2. /^[0-9]/{print b$0;f=1}
  3. f&&/^[^0-9]/{b="";f=0}
  1. line does not start with a number: collect input (titi,toto,tata) 行不以数字开头:收集输入(titi,toto,tata)
  2. line starts with number: print collected lines and $0 , set flag 行以数字开头:打印收集的行和$0 ,设置标志
  3. line does not start with a number any more (flag is set): start over (clear buffer and flag) line不再以数字开头(标志已设置):重新开始(清除缓冲区和标志)

This might work for you (GNU sed): 这可能适合你(GNU sed):

sed -r '/;/{:a;G;s/([^\n]*)\n(.*)/\2\n\1/;s/.//;s/\s*\n/;/g;n;/;/ba;x;z;x};H;d' file

Use the hold space to store the first part of each record. 使用保留空间存储每条记录的第一部分。 When an end part of a record is encountered, append the hold space, rearrange the last part to follow the first part, remove the first newline and replace the remaining newlines by semi-colons. 遇到记录的结尾部分时,追加保留空间,重新排列最后一部分以跟随第一部分,删除第一个换行符并用分号替换剩余的换行符。 Print the record and if the next line is an end part of a record repeat. 打印记录,如果下一行是记录重复的结尾部分。 Otherwise, clear the hold space and append the current line to the hold space. 否则,清除保留空间并将当前行附加到保留空间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM