Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带awk/tr/sed的bash条件getline?_Bash_Awk_Sed_Tr - Fatal编程技术网

带awk/tr/sed的bash条件getline?

带awk/tr/sed的bash条件getline?,bash,awk,sed,tr,Bash,Awk,Sed,Tr,我正在努力解决这个问题,我想把一组行连接成一行。 我的文件的每一行(titi/toto/tata)都有2或3个字段,用“;”分隔 所以我的输入是这样的: 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 我需要这个输出: titi1;titi2;titi3;43;75;97 titi1;titi2;titi3;1;2;87 toto1;toto2;t

我正在努力解决这个问题,我想把一组行连接成一行。 我的文件的每一行(titi/toto/tata)都有2或3个字段,用“;”分隔 所以我的输入是这样的:

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
我需要这个输出:

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
因此,您可以看到前3行是信息(toto/tata等),在以数字开头之后,每行都应该重复这些信息

首先,我的输入只有一行数字,所以它是一个4乘4的分组。因此,我在论坛中搜索了一个示例,并使用如下getline执行此操作:

awk '{getline b; getline c; getline d;printf("%s %s %s %s\n",$0,b,c,d)}'
但后来我开始有2个甚至3个数字对齐。。。
因此,我正在努力做一个“conditional”,理解每次看到以数字开头的lign时,它都应该重复前3个lign。

请尝试以下内容

awk '
{
  sub(/ +$/,"")
}
/^[a-zA-Z]+/{
  if(val && flag){
    val=""
  }
  val=val?val ";" $0:$0
  flag=""
  next
}
{
  flag=1
  print val ";" $0
}'  Input_file
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
解决方案2:如果您的输入文件的最后一行可能是
tot
等,并且您也想打印它,那么请使用以下命令

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

awk -F';' 'NF==1{if(b){a=b=""};a=a$0FS;next}{b=1;$0=a$0}1' infile
而且更容易理解

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

该计划应:

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

  1. /^[^0-9]/{b=b$0";"}
  2. /^[0-9]/{print b$0;f=1}
  3. f&&/^[^0-9]/{b="";f=0}
  • 行不以数字开头:收集输入(titi、toto、tata)
  • 行以数字开头:打印收集的行和
    $0
    ,设置标志
  • 行不再以数字开头(已设置标志):重新开始(清除缓冲区和标志)
  • 编写您的原始脚本-请参阅为什么不为此(或大多数其他情况)使用getline,以及如何在极少数情况下正确调用getline(如果合适的话)。

    这可能适用于您(GNU-sed):


    使用保留空间存储每条记录的第一部分。当遇到记录的结束部分时,追加保留空间,重新排列最后一部分以跟随第一部分,删除第一个换行符并用分号替换剩余的换行符。打印记录,如果下一行是记录的结束部分,请重复。否则,请清除保留空间,并将当前行附加到保留空间。

    谢谢,我马上查看。