【问题标题】:Make reference to a file in a regular expression在正则表达式中引用文件
【发布时间】:2014-04-28 22:31:47
【问题描述】:

我有两个文件。一个是 SALESORDERLIST,如下所示

ProductID;ProductDesc
1,potatoes 1 kg.
2,tomatoes 2 k
3,bottles of whiskey 2 un.
4,bottles of beer 40 gal

(ProductID;ProductDesc) 标头实际上不在文件中,因此请忽略它。 在另一个文件 POSSIBLEUNITS 中,我已经 - 你猜到了 - 可能的单位,以及它们的等价物:

u;u.;un;un.;unit
k;k.;kg;kg.,kilograms

这是我使用正则表达式的第一天,我想知道如何获取 SALESORDERLIST 中的条目,其单位出现在 POSSIBLEUNITS 中。在我的示例中,我想排除条目 4,因为 'gal' 未在 POSSIBLEUNITS 文件中列出。

我说的是正则表达式,因为我还有一个需要匹配的标准:

egrep "^[0-9]+;{1}[^; ][a-zA-Z ]+" SALESORDERLIST

从这些结果条目中,我想得到那些以有效单位结尾的条目。

谢谢!

【问题讨论】:

  • 你可能应该看看像awkgrep 这样的工具来实现你想要的,一个正则表达式本身,不解析文件,它解析字符串。 正则表达式是用于描述搜索模式的特殊文本字符串。 regexbuddy.com/regex.html
  • @Tuga 不过,它可以在 bash 中完成。
  • @ooga 据我所知awkgrep 在 bash 中运行,但 OP 仅使用正则表达式无法达到预期结果。
  • @iL_Marto 不要在这里发帖,更新你的问题。
  • @Tuga 当然,它们“在 bash 中运行”(嗯,不完全是 in bash,但它们可以在 from bash 中运行)。我只是说它可以用 bash 本身来完成,因为 bash 可以从文件中读取行并且可以将子表达式与简单的正则表达式匹配。我并不是说这是最好的方法,但这是一个有趣的练习。

标签: regex bash shell


【解决方案1】:

实现你想要的一种方法是:

cat SALESORDERLIST | egrep "\b(u|u\.|un|un\.|unit|k|k\.|kg|kg\.|kilograms)\b"


1,potatoes 1 kg.
2,tomatoes 2 k
3,bottles of whiskey 2 un.

元字符 \b 是一个锚点,允许您执行“whole words only”搜索 \bword\b 形式的正则表达式。

http://www.regular-expressions.info/wordboundaries.html

【讨论】:

    【解决方案2】:

    一种方法是创建一个 bash 脚本,例如称为 findunit.sh

    while read line
    do
        match=$(egrep -E "^[0-9]+,{1}[^, ][a-zA-Z ]+" <<< $line)    
        name=${match##* }
            # echo "$name..."
            found=$(egrep "$name" /pathtofile/units.txt) 
            # echo "xxx$found"
            [ -n "$found" ] && echo $line
    done < $1
    

    然后运行:

    findunit.sh SALESORDERLIST
    

    我的输出是:

    1,potatoes 1 kg.
    2,tomatoes 2 k
    3,bottles of whiskey 2 un.
    

    【讨论】:

      【解决方案3】:

      一个完全用 bash 做的例子:

      declare -A units
      
      while read line; do
        while [ -n "$line" ]; do
          i=`expr index $line ";"`
          if [[ $i == 0 ]]; then
            units[$line]=1
            break
          fi
          units[${line:0:$((i-1))}]=1
          line=${line#*;}
        done
      done < POSSIBLEUNITS
      
      while read line; do
        unit=${line##* }
        if [[ ${units[$unit]} == 1 ]]; then
          echo $line
        fi
      done < SALESORDERLIST
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-14
        • 1970-01-01
        • 1970-01-01
        • 2018-04-18
        相关资源
        最近更新 更多