51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 1892|回复: 5
打印 上一主题 下一主题

[讨论] shell 脚本问题求指教

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2017-6-9 13:42:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
背景
本想每天刷一道leetcode,保持学习,但第一道就被困住了
题目如下
  1. Given a text file file.txt that contains list of phone numbers (one per line), write a one liner bash script to print all valid phone numbers.

  2. You may assume that a valid phone number must appear in one of the following two formats: (xxx) xxx-xxxx or xxx-xxx-xxxx. (x means a digit)

  3. You may also assume each line in the text file must not contain leading or trailing white spaces.

  4. For example, assume that file.txt has the following content:

  5. 987-123-4567
  6. 123 456 7890
  7. (123) 456-7890
  8. Your script should output the following valid phone numbers:
  9. 987-123-4567
  10. (123) 456-7890
复制代码
我的解法
  1. #!/bin/bash
  2. pattern1="^[0-9]{3}-[0-9]{3}-[0-9]{4}$"
  3. pattern2="^\([0-9]{3}\) [0-9]{3}-[0-9]{4}$"

  4. cat ./file.txt | while read line
  5. do
  6. #echo "ori=$line"
  7.         if [[ $line =~ $pattern1 ]] || [[ $line =~ $pattern2 ]] ; then
  8.                 echo $line
  9.         fi
  10. done
复制代码
结果是一个都没匹配出来查找问题的时候,尝试改成
  1. #!/bin/bash
  2. pattern1="^[0-9]{3}-[0-9]{3}-[0-9]{4}$"
  3. pattern2="^\([0-9]{3}\)\s[1][0-9]{3}-[0-9]{4}$"

  4. cat ./file.txt | while read line
  5. do

  6. echo "ori=$line"
  7.         if [[ $line =~ ^[0-9]{3}-[0-9]{3}-[0-9]{4}$ ]] || [[ $line =~ ^\([0-9]{3}\)' '[0-9]{3}-[0-9]{4}$ ]] ; then
  8.                 echo $line
  9.         fi
  10. done
复制代码
输出符合期望,如果在正则表达式附近加上双引号,则一个都匹配不出来,便以为表达式不可以用字符串的形式,于是修改脚本为
  1. #!/bin/bash
  2. pattern1=^[0-9]{3}-[0-9]{3}-[0-9]{4}$
  3. pattern2=^\([0-9]{3}\)' '[0-9]{3}-[0-9]{4}$

  4. cat ./file.txt | while read line
  5. do

  6. echo "ori=$line"
  7.         if [[ $line =~ ${pattern1} ]] || [[ $line =~ ${pattern2} ]] ; then
  8.                 echo $line
  9.         fi
  10. done
复制代码

发现只有第一个正则表达式work了,第二个依然没有匹配出来
那么如果我想用变量的方式让第二个正则表达式work,该怎么修改?



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏
回复

使用道具 举报

该用户从未签到

2#
发表于 2017-6-9 14:47:23 | 只看该作者
给出一种方案:
awk '/\[0-9]{3}) |[0-9]{3}-)[0-9]{3}-[0-9]{4}$/ {print $0}' file.txt

建议把不符合的输入内容也提供出来,方便使用你的代码调试。
回复 支持 反对

使用道具 举报

该用户从未签到

3#
发表于 2017-6-9 14:48:49 | 只看该作者
话题中一共给了3个方法,经在leetcode.com网站上验证和测试,
方法1可行;
方法2注释掉echo "ori=$line"后也可行;
方法3:可以用引号括起来,但空格两边的单引号需要去掉。
  1. #!/bin/bash
  2. pattern1="^[0-9]{3}-[0-9]{3}-[0-9]{4}$"
  3. pattern2="^\([0-9]{3}\) [0-9]{3}-[0-9]{4}$"

  4. cat ./file.txt | while read line
  5. do

  6. # echo "ori=$line"
  7.         if [[ $line =~ ${pattern1} ]] || [[ $line =~ ${pattern2} ]] ; then
  8.                 echo $line
  9.         fi
  10. done
复制代码
回复 支持 反对

使用道具 举报

该用户从未签到

4#
发表于 2017-6-9 14:49:23 | 只看该作者
楼上正解, 方法2 echo "ori=$line" 是否注释似乎不影响吧。
回复 支持 反对

使用道具 举报

该用户从未签到

5#
发表于 2017-6-9 14:50:12 | 只看该作者
小爸爸 发表于 2017-6-9 14:49
楼上正解, 方法2 echo "ori=$line" 是否注释似乎不影响吧。

对于完成一个具体的工作来说,echo是一条调试信息。但对于这个题来说,echo就影响了最终的结果,没有必要打印无关的内容。
回复 支持 反对

使用道具 举报

该用户从未签到

6#
发表于 2017-6-9 14:51:06 | 只看该作者
我之前用方法一在本地调试一直过不了,所以后来才会把表达式改的这么诡异,相同的输入用方法二就可以过,所以没有怀疑环境本身;刚用leetcode试了一下方法一,确实过了,看来我给在本地找找原因了,3Q~
回复 支持 反对

使用道具 举报

本版积分规则

关闭

站长推荐上一条 /1 下一条

小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

GMT+8, 2024-9-21 11:05 , Processed in 0.067421 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2024 Comsenz Inc.

快速回复 返回顶部 返回列表