在CSV UNIX中删除双引号之间的\ n

时间:2013-11-25 20:54:29

标签: python perl shell unix aix

我有一个由Z / OS的IBM Change Data Delivery生成的平面文件。数据中有新行或\n。我找到了一种方法来使用awk命令替换它们中的大多数,但似乎有一个小错误。如果引号中带有奇数引号的行,则不会用空格替换\n。出于某种原因,我必须循环两次才能获得大部分内容。我留下了1条仍然有\n的记录。这是一个样本。

"2013-11-19 10:09:09","0","I","NOT SET   ","
simple string                            "

需要基本上:

"2013-11-19 10:09:09","0","I","NOT SET   ","simple string                            "

以下是我正在使用的代码:

#For loop#
for a in 1 2 
do
  awk -F'"' '$NF""{printf("%s ", $0);next}1' $1 > $1.filter
  rm -f $1
  mv $1.filter $1
  echo $a
done

此文件中包含大约100k条记录。它被数据收集拾取,但看到记录的\n抛出,因为它认为下一行应该是新记录。

谢谢, 约什

编辑:

我发现这个Perl命令可以执行每次操作,但最终仍会遇到与上面相同的错误。

$ perl -p -le 's/\n+/ /g'

4 个答案:

答案 0 :(得分:4)

这是一种方法:

sed -n -e ':b; /^[^"]*"[^"]*\("[^"]*"[^"]*\)*$/ { N; s/\
//; bb; }; p; '

在伪代码中它是

label foo:
  if we have an odd number of quotes:
    read and append the next line
    remove the line feed
    goto foo

print line

示例输出:

$ cat file
"2013-11-19 10:09:09","0","I","NOT SET   ","
simple string                    "
"normal data",42
"some other
string"
$ sed -n -e ':b; /^[^"]*"[^"]*\("[^"]*"[^"]*\)*$/ { N; s/\
//; bb; }; p; ' < file
"2013-11-19 10:09:09","0","I","NOT SET   ","simple string                  "
"normal data",42
"some otherstring"
$ 

请注意,使用反斜杠转义的任何引号都会破坏它("foo\"bar"),而使用引号("foo""bar")转义的引号将起作用。确保您知道您正在使用的CSV方言。

答案 1 :(得分:2)

我已经研究过glenn jackman的建议,并在python中使用过一个解决方案。这是我使用Python的代码:

#!/usr/bin/python

import sys, csv, os

inputfile=sys.argv[1]
outputfile=sys.argv[1] + '.filter'
newtext=' '

print inputfile
print outputfile

with open(inputfile, "rb") as input:
  with open(outputfile, "wb") as output:
    w = csv.writer(output, delimiter=',', quotechar='"', quoting=csv.QUOTE_NONNUMERIC, lineterminator='\n')
    for record in csv.reader(input):
      w.writerow(tuple(s.replace("\n", newtext) for s in record))

os.rename(outputfile, inputfile)

感谢大家的帮助。希望有同样问题的人会发现这一点。我对此解决方案的唯一问题是它在所有字段周围添加引号,包括空字段。

谢谢,乔希

编辑:

我能够使用perl快速删除彼此旁边的所有双引号。

perl -pi -le 's/""//g' data

答案 2 :(得分:1)

我会使用带有CVS解析器的语言。尝试解析当前行,如果有错误,请加入下一行并再试一次:例如,使用ruby:

ruby -rcsv -ne '
  chomp
  loop do
    begin
      row=CSV.parse_line($_)
      # if no error thrown, we have a parseable line
      puts row.inspect
      break
    rescue
      # grab the next line and try again
      $_ += gets
    end
  end
' << END
a,b,c,d,e
1,2,3,4,5
"2013-11-19 10:09:09","0","I","NOT SET   ","
simple string                            "
"a 1","b 2","c 3","d 4","e 5"
END
["a", "b", "c", "d", "e"]
["1", "2", "3", "4", "5"]
["2013-11-19 10:09:09", "0", "I", "NOT SET   ", "simple string                            "]
["a 1", "b 2", "c 3", "d 4", "e 5"]

答案 3 :(得分:0)

sed -n -e '/"/ {
   s/:/:d/g;s/\\"/:e/g
:b 
      /^\(\("[^"]*"\)*[^"]*\)*"\([^"]*\)$/ { 
      N
      s/\
//
      b b
      }
   s/:e/\\"/g;s/:d/:g/
  }
p' YourFile

之前使用“翻译”。这使用了更多的cpu但通过throug逃过了“