【问题标题】:Remove LF inside specific field and nowhere else删除特定字段内的 LF,其他任何地方都没有
【发布时间】:2020-02-04 01:33:34
【问题描述】:

我被要求清理 MongoDB 集合中的数据,我们必须存储地址和通用客户联系数据。

数据偶尔包含回车,当我将数据推送到 MySQL 表时,这往往会破坏加载过程。我的代码使用 Javascript 在关键字段上执行 a replace(/\n//g, '')。但是,数据转储仍然显示混乱,如下所示:

"_id"|"UserID"|"PhoneNumber"|"Source"|"PrivateLabelID"|"OptOut"|"Blocked"|"Deleted"|"Note"|"CreatedAt"|"UpdatedAt"|"FirstName"|"LastName"|"Email"|"Custom1"|"Custom2"|"Custom3"|"Custom4"|"Custom5"|"GroupIDs"
"5e37169df3369f47583355dc"|"127342"|"8645169963"|"1"|"1"|"undefined"|"undefined"|"undefined"|"Timothy.. I mainly buy in the SW area of Florida. Please send me what you have"|"1580668573"|"1580668573"|"Lee"|"Burnside"|"clemsonworldentertainment@gmail.com"|"undefined"|"undefined"|"undefined"|"undefined"|"undefined"|"[object Object]"
"5e3712c6958b2b1896070f2b"|"127342"|"8452063505"|"1"|"1"|"undefined"|"undefined"|"undefined"|"Yes I am looking in the lower to central Florida market. Multi family units."|"1580667590"|"1580667591"|"Daniel "|"Lepore"|"daniellepore@icloud.com"|"undefined"|"undefined"|"undefined"|"undefined"|"undefined"|"[object Object]"
"5e37107f61befe0bea740cfa"|"127342"|"3867770002"|"1"|"1"|"undefined"|"undefined"|"undefined"|"He's with Habib
His last name is not Thompson that Habib name"|"1580667007"|"1580667007"|"Thompson"|""|""|"undefined"|"undefined"|"undefined"|"undefined"|"undefined"|"[object Object]"
"5e370e08853f2702e40828fa"|"127342"|"4073712312"|"1"|"1"|"undefined"|"undefined"|"undefined"|"Indeed we are looking for Buy, Fix and Sell and strong rentals including duplexes, triplexes etc.
"|"1580666376"|"1580666376"|"Gisela "|"Escobar"|"jbetfinancial@gmail.com"|"undefined"|"undefined"|"undefined"|"undefined"|"undefined"|"[object Object]"
"5e3709f351798f62ea228e08"|"127342"|"4077774697"|"1"|"1"|"undefined"|"undefined"|"undefined"|"Yes I am buying in that area or any area in Florida if the numbers are right
only in Flipping houses

“注释”字段是这里的挑战。我运行cat --show-all filename 时,我在每条记录的末尾看到了LF“$”字符以及“Note”字段内。

我尝试了tr '\n' ' ' <filename,但它删除了所有 LF 字符。有没有办法只删除“注释”字段内的 LF 字符?

PS:Raw data file(9 行)如果您想自己检查。

【问题讨论】:

  • 你可能需要解释一下!
  • 我们需要知道字段中间的实际字符是什么......此时无法判断我们是在谈论dos还是unix文件;我建议将有问题的字段放入自己的文件中,在不可打印字符之前和之后留下几个字符,然后通过od 运行文件,例如,假设样本数据在test.dat 中,所以运行@ 987654328@ 并将整个输出放在您的问题中。
  • @markp 我假设他正在寻找一个用空格替换 \n 的正则表达式。但不适用于“\n
  • @user171558,当然,删除一个(或多个)嵌入的 cr/lf 的 ....

标签: javascript mongodb bash newline


【解决方案1】:

我的假设是您正在尝试删除 \n,除非它前面有引号

sed ':a;N;$!ba;s/[^"]\n/ /g' filename.txt

【讨论】:

    【解决方案2】:

    假设:

    • 当文件通过od 运行时,嵌入的返回/换行显示为单个\n
    • 文件中可能嵌入了多个\n
    • 一旦嵌入的\n(s) 被删除,那么每行应该有20 个字段(分隔符=|

    对于这个示例,我将使用每行只有 6 个字段的较小文件。此处添加 cmets 仅用于文档目的,即实际数据文件中不存在 cmets:

    $ cat abc.dat
    f1|f2|f3|f4                    # line1 part1
    f4|f5|f6                       # line1 part2
    g1|g2|g3|g4 g4|g5|g6           # line2
    h1|h2|h3|h4 h4|h5|h6           # line3
    i1|i2|i3|i4                    # line4 part1
    f4|i5|i6                       # line4 part2
    j1|j2|j3|j4 j4|j5|j6           # line5
    k1|k2|                         # line6 part1
    k3|k4 k4|k5                    # line6 part2
    |k6                            # line6 part3
    l1|l2|l3|l4 l4|l5|l6           # line7
    

    我们不再专注于去除嵌入的\n,而是将行(中间有空格)附加在一起,直到我们有6个字段,然后我们将添加自己的\n最后。

    一个awk 解决方案(同样,cmets 仅用于文档目的):

    awk -F"|" '
    BEGIN          { prevNF=0    }                             # preset our previousNF to 0
    (NF+prevNF)==6 { printf "%s\n",$0 ; prevNF=0 ; next      } # if we have 6 fields then print current line and terminate with a \n, then skip to next line of input
                   { printf "%s " ,$0 ; prevNF=(prevNF+NF-1) } # otherwise print the line terminated with a space and save our current NF minus 1 (to account for fact current last field == first field of next line)
    END            { printf "\n" }                             # one final \n to get us onto a new/blank line
    ' abc.dat
    

    对我的abc.txt 文件运行上述代码可以得到:

    f1|f2|f3|f4 f4|f5|f6
    g1|g2|g3|g4 g4|g5|g6
    h1|h2|h3|h4 h4|h5|h6
    i1|i2|i3|i4 f4|i5|i6
    j1|j2|j3|j4 j4|j5|j6
    k1|k2| k3|k4 k4|k5 |k6
    l1|l2|l3|l4 l4|l5|l6
    

    这是bash fiddle

    【讨论】:

      【解决方案3】:

      您是否考虑过在 MongoDB 中使用聚合在导出之前进行更改?

      如果您需要保持原始数据不变,请使用修改后的数据创建一个新集合:

      db.inputCollection.aggregate([{$addFields:{Note:{$reduce:{input:{$split:["$Note","\n"]}, initialValue:"", in:{$concat:["$$value","$$this"]}}}}},{$out:"outputCollection"}])
      

      分解:

      $addFields 将为每个文档添加新字段,替换任何具有相同名称的字段 将Note 字段设置为$reduce 的结果
      对于 reduce 的输入,通过在换行符 {$split:["$Note","\n"]} 上拆分 Note 字段来创建一个数组
      reduce 的 in 字段指定函数 {$concat:["$$value","$$this"]} 这将当前值连接到前一个之后 管道中的这个阶段大致相当于 .split("/n").join("")

      $out 将输出写入集合名称,供您导出

      如果可以修改原始集合,您可以使用以下内容更新该字段:

      db.inputCollection.find({Note:/\n/},{Note:1}).forEach(function(d){  
        db.inputCollection.update({_id:d._id},{$set:{Note:d.Note.replace(/\n/g, '')}})
      })
      

      【讨论】:

      • 我不允许修改原始集合,但您的方法在这一点上最有意义。我已经修改了我的代码以进行这样的替换 ....while (cursor.hasNext()) { var record = cursor.next(); print( ... "\"" + record.Note.replace(/\r\n//g, '') + "\"|" ....
      猜你喜欢
      • 2020-07-19
      • 1970-01-01
      • 2020-09-28
      • 1970-01-01
      • 2017-03-29
      • 2013-03-04
      • 2016-10-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多