【问题标题】:Finding columns with only white space in a text file and replace them with a unique separator在文本文件中查找只有空格的列并用唯一的分隔符替换它们
【发布时间】:2015-09-01 07:57:48
【问题描述】:

我有一个这样的文件:

aaa  b b ccc      345
ddd  fgt f u      3456
e r  der der      5 674

如您所见,我们可以分隔列的唯一方法是找到只有一个或多个空格的列。我们如何识别这些列并将它们替换为唯一的分隔符,例如,。

aaa,b b,ccc,345
ddd,fgt,f u,3456
e r,der,der,5 674

注意:
如果我们找到所有带有一个或多个空格的连续列(没有别的)并将它们替换为,(所有列),问题将得到解决。

josifoski 更好地解释了这个问题: 每个矩阵字符块,如果都是“空格”,那么所有块都应该在每一行上垂直替换为一个。

【问题讨论】:

  • 什么定义了列?它们都是 3 个字符长吗?
  • f和u之间是一个空格,而fgt和f之间是多一个空格?
  • 为什么b b 是单列?
  • 哦对了,所以我们只需要找到由空格分隔的列,其中包含空格,以确定哪些列包含空格。
  • @josifoski 没有你可以在 python 中进行的文本操作,而你不能在 awk 中进行。事实上,我们看到许多编写 Python 脚本的人提出的问题,询问如何调用 awk 来操作 Python 脚本中的文本,但从来没有反过来。

标签: regex r bash awk sed


【解决方案1】:
$ cat tst.awk
BEGIN{ FS=OFS=""; ARGV[ARGC]=ARGV[ARGC-1]; ARGC++ }
NR==FNR {
    for (i=1;i<=NF;i++) {
        if ($i == " ") {
            space[i]
        }
        else {
            nonSpace[i]
        }
    }
    next
}
FNR==1 {
    for (i in nonSpace) {
        delete space[i]
    }
}
{
    for (i in space) {
        $i = ","
    }
    gsub(/,+/,",")
    print
}

$ awk -f tst.awk file
aaa,b b,ccc,345
ddd,fgt,f u,3456
e r,der,der,5 674

【讨论】:

  • 快!需要解释
  • 随时提供上述解释:-)。我认为这非常简单明了,可能有一些对新手手册页的引用,所以我宁愿 OP 考虑一下,如果有问题,请提出问题。
  • @EdMorton 我认为它至少值得一点解释。这部分ARGV[ARGC]=ARGV[ARGC-1]; ARGC++ 肯定会让新手感到困惑,即使他们确实阅读了手册页。我想你忘记了当你不熟悉语言时遵循程序逻辑是多么困难。
  • 我宁愿回答问题也不愿解释可能令人困惑的每一行。在 google 和手册页之间,我认为一点点努力就能回答任何问题,但我很乐意为任何在付出一点努力后无法弄清楚的人回答任何问题。
【解决方案2】:

awk 中的另一个

awk 'BEGIN{OFS=FS=""}  # Sets field separator to nothing so each character is a field

FNR==NR{for(i=1;i<=NF;i++)a[i]+=$i!=" ";next}  #Increments array with key as character 
                                  #position based on whether a space is in that position.
                                  #Skips all further commands for first file.
     {                            # In second file(same file but second time)
        for(i=1;i<=NF;i++)        #Loops through fields
           if(!a[i]){             #If field is set
              $i=","              #Change field to ","
              x=i                 #Set x to field number
              while(!a[++x]){     # Whilst incrementing x and it is not set
                 $x=""            # Change field to nothing
                 i=x              # Set i to x so it doesnt do those fields again
              }
           }
      }1' test{,} #PRint and use the same file twice

【讨论】:

  • @EdMorton 但是标点符号!它不见了:(
  • 是的,我想知道有人多久会接受一个注释脚本并认为他们会通过添加标点符号来“修复”它:-)。
【解决方案3】:

由于您还标记了此,因此这是使用R 包readr 的可能解决方案。看起来您想读取固定宽度文件并将其转换为逗号分隔文件。您可以使用read_fwf 读取固定宽度文件,使用write_csv 写入逗号分隔文件。

# required package
require(readr)
# read data
df <- read_fwf(path_to_input, fwf_empty(path_to_input))
# write data
write_csv(df, path = path_to_output, col_names = FALSE)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-14
    • 2014-12-07
    • 2016-01-19
    • 2022-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多