linux - 如何使用 awk sed 或 shell 脚本合并两个不同的行

标签 linux shell awk sed

我有一个文件 file.txt。我必须将两个不同的行合并为一个。

文件.txt

                  linux-
02-10-2018 11:50  is-a-opensource  user    file
02-10-2018 11:46  linux-userfile   user    file1
                                   user-1
02-10-2018 11:40  linux-userfile   user    file2
                  linux-           user-2
02-10-2018 11:30  linux-userfile   user    file3

预期输出

 02-10-2018 11:50  linux-is-a-opensource  user    file
 02-10-2018 11:46  linux-userfile         user    file1
 02-10-2018 11:40  linux-userfile         user1user    file2
 02-10-2018 11:30  linux-linux-userfile         user-2user    file3

如有任何建议,我们将不胜感激。

我尝试了下面的命令,但没有成功。

  $ awk ' /^ +/{ gsub(/^ +/," ");a=a $0; next }{ $2=$2a;a=""}1' file.txt 

我遇到了错误

  02-10-2018 11:50 linux- is-a-opensource user file
  02-10-2018 11:46 linux-userfile user file1
  02-10-2018 11:40 user-1 linux-userfile user file2
  02-10-2018 11:30 linux-           user-2 linux-userfile user file3

我尝试了以下链接作为引用,但我仍然遇到同样的错误 How to Merge 2 diffrent lines in linux by using awk

How to merge two rows in a same row from a text file in linux shell script

最佳答案

由于很难确定字符串属于哪一列,我做如下假设:

  • 完全对齐且空格分隔

所以下面脚本将假定:

  • 不以日期开头的行将合并到
  • 列宽由行的列宽决定

注意:如果您的文件与空格对齐(制表符和空格的组合),我们无法使用字段分隔符“\t”来区分字段,因为制表符的数量取决于在字段宽度上。

这是经过测试的脚本:

# If you have a tab-aligned file, replace all tabs by the
# correct sequence of spaces. In this example, we assume a single
# tab is equivalent to 8 spaces. Adopt if needed
{ gsub(/\t/,"        ",$0) }

# If the line does not start with a combination of numbers and hyphens
# it is a line that needs to be merged into the next line.
# store it and move to the next line
($1 !~ /^[-0-9]+$/) { tomerge=$0; next }

# If we picked up a tomerge line, try to figure out the fields
# by looking into the current line and determining the field widths.
(tomerge != "")  {
      # extract fields
      n=1 
      for(i=1;i<NF;++i) {
         m=index($0,$(i+1))
         field[i]=substr(tomerge,n,m-n)
         sub(/^[[:blank:]]*/,"",field[i])  # remove leading blanks
         sub(/[[:blank:]]*$/,"",field[i])  # remove trailing blanks
         n=m
      }
      field[NF]=substr(tomerge,n)
      # perform merging
      for(i=1;i<=NF;++i) $i= field[i] $i
      # reset the tomerge value
      tomerge=""
}
# print the line
{ $1=$1;print $0 }

哪些输出:

$ awk -f script.awk file.txt
02-10-2018 11:50 linux-is-a-opensource user file
02-10-2018 11:46 linux-userfile user file1
02-10-2018 11:40 linux-userfile user-1user file2
02-10-2018 11:30 linux-linux-userfile user-2user file3

如果你想让它对齐,你可以把它传递给column -t as

$ awk -f script.awk file.txt | column -t

关于linux - 如何使用 awk sed 或 shell 脚本合并两个不同的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52676820/

相关文章:

bash - 需要一个 shell 脚本来删除除 *.pdf 之外的所有文件

linux - 如何用shell函数制作 "dictionary"?

unix - Awk:使用包含标题的部分修改 csv

linux - awk 在输出中打印不必要的新行

linux - 如何使用 ed 在命令输出后追加一行

java - Java如何获取目录的最新文件

linux - bash 脚本多重条件

Linux 内核实用函数,以符号字符串作为输入并返回其地址

java - 格式化 Linux 命令的输出

windows - BASH:确定脚本是从虚拟机(Ubuntu)还是W10 bash应用程序调用的?