【问题标题】:How can I replace a the pattern ",," with <RETURN> in awk?如何在 awk 中用 <RETURN> 替换模式“,”?
【发布时间】:2018-04-30 17:13:54
【问题描述】:

我正在做一个 ldapsearch 查询,它返回的结果如下

John Joe jjoe@company.com +1 916 662-4727  Ann Tylor Atylor@company.com (987) 654-3210  Steve Harvey sharvey@company.com 4567893210  (321) 956-3344  ...

您可以在每个个人记录输出之间看到一个空格,电话号码可能以 +1 开头,也可能在数字或括号之间有空格,最后在个人记录之间有两个空格。例如:

我想将这些条目转换为以下格式:

John,Joe,jjoe@company.com,(916) 662-4727
Ann,Tylor,Atylor@company.com,(987) 654-3210
Steve,Harvey,sharvey@company.com,(456) 789-3210,(321) 956-3344
...

所以基本上用一个逗号“,”替换一个空格,用一个逗号替换两个空格,这样最后我每行就有一个个人记录(逗号分隔)。示例:

我正在尝试 awk 并设法用 "," 替换,这使得

<blank><blank> to double comma ",,". 
But can't figure out how to turn ",," to <RETURN>

2017 年 11 月 22 日 ----****** 更新 ******-------- 2017 年 11 月 22 日

我把这条赛道弄得太拥挤了。我将发布一个包含更多细节的新问题。

【问题讨论】:

  • 你试过什么?你的尝试在哪里有问题?请将您的尝试和结果添加到问题中,以便我们知道您需要什么帮助。
  • 另外,Shane Harvey 有两个电话号码吗?示例输入中最后一个电话号码前的双倍空格使其看起来像是一条新记录。
  • 我在做:ldapsearch -LLL -x -H ldaps:&lt;ldapserver&gt; -b "ou=people,dc=&lt;domain&gt;,dc=edu" -D uid=&lt;id&gt;,ou=applications,dc=&lt;domain&gt;,dc=edu -w &lt;password&gt; &lt;some confidential info&gt; givenname sn mail telephoneNumber | awk -F ":" '{printf $2}{printf "\n"}' | awk -F "uid" '{printf $1}' | tr " " ","
  • 您尝试过的内容是您问题的重要组成部分,应该包含在您的问题中,而不仅仅是事后添加到 cmets。下次您使用 StackOverflow 时,请考虑在问题中包含您目前所做的工作,我相信您会得到更多高质量的答案。
  • @ghoti 好点。这是我第一次提交(使用)StackOverflow。下次我一定会坚持你的建议!

标签: bash awk sed gawk tr


【解决方案1】:

根据您的要求,需要使用sed 进行大量替换。

$ cat sed-script
s/\ \ ([A-Za-z])/\n\1/g;        # replace alphabets which appended double spaced to '\n'
s/\ \ /,/g;                     # replace remaining double spaces to ',' 
s/([A-Za-z]) /\1,/g;            # releace the space appended alphabets to ',' 
s/\+1//;                        # eliminate +1
s/[ ()-]//g;                    # eliminate space, parenthesis, or dash
s/([^0-9])([0-9]{3})/\1(\2) /g; # modify first 3 numeric embraced by parenthesis
s/([0-9]{4}[^0-9])/-\1/g;       # prepend a '-' to last 4 numerics

$ sed -r -f sed-script file 
John,Joe,jjoe@company.com,(916) 662-4727
Ann,Tylor,Atylor@company.com,(987) 654-3210
Steve,Harvey,sharvey@company.com,(456) 789-3210,(321) 956-3344,...

【讨论】:

  • 感谢您的反馈,这很棒。
【解决方案2】:

如果您的 Input_file 与所示示例相同,那么关注 awk 可能会对您有所帮助。

awk --re-interval '{gsub(/[0-9]{3}-[0-9]{4} +/,"&\n");print}'  Input_file

我有旧版本的awk,所以我在新的awk 中提到了--re-interval,无需提及。

说明:在这里也添加解决方案的说明。

awk --re-interval '{               ##using --re-interval to use the extended regex as I have old version of awk.
gsub(/[0-9]{3}-[0-9]{4} +/,"&\n"); ##Using gsub utility(global substitute) of awk where I am checking 3 continuous dots then dash(-) then 4 continuous digits and till space with same regex match and NEW LINE.
print                              ##printing the line of Input_file
}'  Input_file                     ##Mentioning the Input_file here.

【讨论】:

  • 非常感谢您提供详细的解决方案以及 cmets。
【解决方案3】:

为了你的兴趣,你可以用 Perl 说:

perl -e '
while (<>) {
    s/  /\n/g;
    s/ /,/g;
    s/(\+1,)?\(?(\d{3})\)?[-,]?(\d{3})[-,]?(\d{4})/($2) $3-$4/g;
    print;
}' file

【讨论】:

  • @tshiono 您的解决方案就是它!谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-04
  • 2017-02-14
  • 2017-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-24
相关资源
最近更新 更多