Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 使用sed或awk分割数据_Regex_Bash_Shell_Sed_Awk - Fatal编程技术网

Regex 使用sed或awk分割数据

Regex 使用sed或awk分割数据,regex,bash,shell,sed,awk,Regex,Bash,Shell,Sed,Awk,我有很多数据要在CSV中拆分。我的源数据具有以下格式: * USER 'field1' 'mail1@domain.com' 'field3' * USER 'field1' 'mail2@domain.com' 'field3' * USER 'field1' 'mail3@domain.com' 'field3' 以下是我试图获得的输出: field1;mail1@domain.com;field3 field1;mail2@domain.com;field3 field1;mail3@d

我有很多数据要在CSV中拆分。我的源数据具有以下格式:

* USER 'field1' 'mail1@domain.com' 'field3'
* USER 'field1' 'mail2@domain.com' 'field3'
* USER 'field1' 'mail3@domain.com' 'field3'
以下是我试图获得的输出:

field1;mail1@domain.com;field3
field1;mail2@domain.com;field3
field1;mail3@domain.com;field3
规则

  • *行开头的用户
    必须明显剥去
  • field1
    field3
    可以是电子邮件地址,也可以包含
  • 字段1
    可以为空
    '
  • 第二个字段始终是电子邮件地址
  • 每个字段的开头和结尾都有
  • 我的想法是剥离
    *USER
    sed-e的/^*USER/'
    可能是一个起点),然后在“中心”字段中“查找”邮件,然后将左侧和右侧分为两个变量。最后一件事应该是去掉vars上的开头和结尾
    。 不幸的是,我没有这个级别的sed或awk知识。关于如何实现这一点有什么想法吗


    这里有一个例子

    * USER '' 'alberto.cordini@generaligroup.com' 'CORDINI ALBERTO'
    * USER 'moglie delmonte daniele' 'anna.borghi@rpos.com' 'Anna Borghi'
    * USER '' 'annamaria.cravero@generaligroup.com' 'CRAVERO ANNA MARIA'
    * USER '' 'patrizia.dagostino@generaligroup.com' 'D'AGOSTINO PATRIZIA'
    * USER '' 'piero.depra@generaligroup.com' 'DE PRA' PIERO'
    * USER '' 'viviana.dingeo@generaligroup.com' 'D'INGEO VIVIANA'
    

    更新:您可以将此awk用于提供的输入:

    awk -F " '" '{gsub(/^ +| +$/, "", $3);
                  s=sprintf("%s;%s;%s;", $2,$3,$4); gsub(/'"'"';/, ";", s); print s}' file
    ;alberto.cordini@generaligroup.com;CORDINI ALBERTO;
    moglie delmonte daniele;anna.borghi@rpos.com;Anna Borghi;
    ;annamaria.cravero@generaligroup.com;CRAVERO ANNA MARIA;
    ;patrizia.dagostino@generaligroup.com;D'AGOSTINO PATRIZIA;
    ;piero.depra@generaligroup.com;DE PRA' PIERO;
    ;viviana.dingeo@generaligroup.com;D'INGEO VIVIANA;
    
    简单地说:

    $ awk '{print $2,$4,$6}' FS="'" OFS=";" file 
    field1;mail1@domain.com;field3
    field1;mail2@domain.com;field3
    field1;mail3@domain.com;field3
    

    你可以使用sed和awk,这很管用,但像你一样,我不经常使用它们来记忆(我发现它们很笨重)。如果您需要一个可以放入脚本中随时运行的解决方案,那么Ruby解决方案如何?我使用正则表达式,但您不必:

    sample-data.txt

    * USER 'field1' 'mail1@domain.com' 'field3'
    * USER 'field1' 'mail2@domain.com' 'field3'
    * USER 'field1' 'mail3@domain.com' 'field3'
    
    parse.rb

    #!/usr/bin/env ruby
    
    $stdin.each_line do |e|
        matches = e.match /\*\ USER\ '([\w]*)'\ '([\w\@\.]*)'\ '([\w]*)'/
        if matches != nil
            puts "#{matches[1]};#{matches[2]};#{matches[3]}"
        end
    end
    
    从终端/命令行:

    cat sample-data.txt | ruby parse.rb
    
    p、 对我来说,如果这是一次性的问题,我会在Windows中使用记事本+。我会打开文件,然后录制一个宏,然后将宏播放到文件末尾,完成

     sed "s/²/²S/g;s/\\'/²q/g;s/\*[[:blank:]]USER[[:blank:]]\{1,\}'\([^']*\)'[[:blank:]]*'\([^']*\)'[[:blank:]]*'\(.*\)'[[:blank:]]*$/\1;\2;\3/;s/²q/\\'/g;s/²S/²/g" YourFile.csv
    

    假设在一个
    sed
    示例中,没有内部带有
    的字段1是/不是转义的,这取决于引号分隔的字段之间存在单个空格这一事实。如果情况并非如此,则需要修改以使其更加“灵活”

    为了避免shell引用转义(这是一种丑陋的体验),我会将一行代码放入一个文件中-r使用扩展的regexp(避免引用
    ()
    s)。字段1和字段3中的单引号由regexp greediness保留(吃所有东西,包括引号,直到最后一个引号:)

    s、 sed:

    s/\* USER '(.*)' '([^']*)' '(.*)'/\1;\2;\3/
    

    如果你能够添加一个小样本,包含你添加到帖子中的案例/规则,肯定会更容易提供帮助。我在下面发布了一个示例,为什么使用
    '
    而不是
    来包围可能包含
    '
    的名称?…这是在自找麻烦。好吧,这只需稍作改动即可。
    FS=“\047”“
    。有些系统不接受这一点。至少我的solaris boxI喜欢使用开头和结尾撇号作为FS。直到用户O'Hara使用他的真名(谷歌xkcd Johnny Tables提供了一个警示性的故事)为止。仍然得到我的选票…它没有像预期的那样工作。看看下面的例子,你在答案中看到的
    'D'INGEO VIVIANA'
    应该是编辑的?它没有按预期工作。看下面的例子,我必须保存“字段内部(而不是外部)”哦,完美!还有一个问题:是否可以“修剪”电子邮件地址/$3?修剪的意思是修剪电子邮件字段中的空格?巧妙地使用
    “'”
    分隔符。没问题!只是想给你一个选择。
    s/\* USER '(.*)' '([^']*)' '(.*)'/\1;\2;\3/