格式化文本 Awk Sed

Formatting Text Awk Sed

您好,我有一个文件需要以某种格式放入 excel 电子表格中,我不知道该怎么做,如果您能帮助我,我将不胜感激。

这是输入样本

#1

Indiana University—​Bloomington (Kelley) 
Bloomington, IN

90  58  82  86 
#1

Temple University (Fox) 
Philadelphia, PA

95  66  97  95 
#1

University of North Carolina—​Chapel Hill (Kenan-​Flagler) 
Chapel Hill, NC

73  58  100     75 
#4

这是输出

#1, Indiana University—​Bloomington (Kelley) Bloomington, IN,   90, 58, 82, 86,
#1, Temple University (Fox) Philadelphia, PA,           95,     66,     97,     95, 

我在 linux

中使用 shell 脚本

谢谢

虽然您完全可以通过一些 awk 脚本来做到这一点,但我建议您不要那样做。

实际上,awk 对于任何不太复杂的东西都很方便,但是在这里,既然您已经计划使用 Excel,您不妨只导入普通文件,然后在 excel 中对其进行处理、旋转、重塑、拆分。

但是,我 讨厌 Excel 的复杂性,所以这是我的 python2 方法(将其保存为 program.py 并使其可执行为chmod 755 program.py):

#!/usr/bin/python
import sys

wholefile = open(sys.argv[1], "r").read()
parts = wholefile.split("#")

for item in parts:
    lines = item.split("\n")
    output = [ int(lines[0]), lines[2], lines[3],lines[5].split() ]
    print ";".join(output)

和运行这是

program.py input.txt > output.csv

编辑:错字,以及:

我倾向于经常这么说,但是在 shell 脚本中做一些不是很希望调用大量命令的事情通常远不如使用任何通用脚本有效语。 Python 随处可见,以至于我发现自己很少写 bash 脚本。

EDIT2:好的,所以您的主机上没有 python。吓人;P.使用 bash 的内置 read 函数 (man read).

如果您不尝试以基于行的方式使用 GNU awk 和 mawk,这将非常简单。我们将在行首使用 # 作为记录分隔符,使用换行符作为字段分隔符。那么:

awk -v RS='(^|\n)#' -F'\n' 'NR > 1 { gsub(/ +/, ", ", ); print "#"  ", "  " "  ", "  }' filename

即:

NR > 1 {                              # the first record is the empty bit before
                                      # the first separator, so we skip it
  gsub(/ +/, ", ", )                # then: insert commas in the number row
  print "#"  ", "  " "  ", "  # and reassemble the record in the right
                                      # format for printing.
}

使用正则表达式作为记录分隔符并不严格符合 POSIX,但在 gawk 和 mawk 之间,您将涵盖大部分内容。

awk脚本解决问题:

/^#[0-9]/ {current = [=10=]}

/\([A-Za-z ]+\)/ { current = current "," [=10=]}

/[A-Z]+$/ { current = current [=10=]}

/^[0-9]+/ {current = current ","  ","  ","  "," ; print current}

用法:

cat yourdatafile | awk -f script.awk > output.csv

解释:

每个正则表达式匹配不同行上的模式并执行正则表达式旁边该​​行的操作。

  • 对于#number,initialize/overwrite一个带有#number 的当前变量。
  • 对于没有状态的文本信息,以逗号开头添加到当前变量中
  • 对于带有State的文本信息,将其添加到当前变量中,开头不带逗号
  • 对于数字列表,将它们添加到当前变量,并在每个数字之间加上逗号,然后打印当前变量
 sed '#n;/[0-9 ]/ s/  */, /g;/^ *$/d;H;$!b;g;s/.//;s/\n\([^#]\)/, /g;p' YourFile
  • 删除并预格式化输入行
  • 保留剩余信息
  • 最后,加载缓冲区
  • 删除第一个换行符
  • , 和后面的字符本身替换 # 后面没有跟的任何新行
  • 打印结果

如果最后一个 , 是强制性的(通常不在 csv/excel 文件中)用这个 ;/[0-9 ]/ {s/ */, /g; s/$/,/;}

调整 /[0-9 ]/ s/ */, /g

这是使用 awk 的另一种方法,仅操作输出字段分隔符 (OFS) 和输出记录分隔符 (ORS):

grep -v '^$' infile |      # remove empty lines
awk 'NR%4 { ORS=", "; OFS=" " } NR%4 == 0 { ORS="\n"; OFS=", " } ='

输出:

#1, Indiana University—​Bloomington (Kelley), Bloomington, IN, 90, 58, 82, 86
#1, Temple University (Fox), Philadelphia, PA, 95, 66, 97, 95
#1, University of North Carolina—​Chapel Hill (Kenan-​Flagler), Chapel Hill, NC, 73, 58, 100, 75
#4,