【问题标题】:UNIX Script for a list of strings find those not in any file用于字符串列表的 UNIX 脚本查找不在任何文件中的字符串
【发布时间】:2010-03-03 14:55:04
【问题描述】:

我正在解析属性文件以获取属性列表。我想检查使用这些属性的所有位置(目标目录和子目录),标记属性文件中定义但未在目标目录中的任何位置使用的任何位置。到目前为止我有

FILE=$1
TARGETROOT=$2

for LINE in `grep '[A-Z]*=' $FILE | awk -F '=' '{print$1}'`;
do

done;

在这个循环中,我想找到那些不在 $TARGETROOT 或其子目录中的 $LINE 变量

示例文件

Properties File
a=1
b=2
c=3
...

许多文件包含对属性的引用

FILE 1
PropAValue = a

【问题讨论】:

    标签: unix scripting grep


    【解决方案1】:

    检查grep的返回码

    您可以通过检查 $?变量。

    如果为 0 则找到字符串,否则找不到字符串。如果不是 0,则将该字符串添加到“未找到”数组中,这应该是您的未找到属性列表。

    grep "string" 
    if [$? -ne 0] 
    then 
       string not found 
    fi
    

    【讨论】:

    • 这听起来像是答案,你能给我一个你如何检查的例子吗?
    • $?变量保存最后执行的命令的退出代码。像这样: grep "string" if [$? -ne 0] 然后找不到字符串 fi
    • 每次你不必要地评估 $?,一只小猫就死了。只需:如果 grep ...;那么……fi
    • 需要更多空间:if [ $? -ne 0 ]。我同意威廉的观点:直接在条件中使用结果;在少数情况下您需要 $?,而这似乎不是其中之一。
    【解决方案2】:
    • xyz 可以任意大的情况下使用xyz | while read PROP 而不是for PROP in ``xyz``; do
    • 如果grep匹配失败,使用grep -l ... >/dev/null || xyz执行xyz,如果找到一个匹配则丢弃grep输出do /dev/null而不执行xyz-l停止grep之后第一场比赛,如果有的话,让它更有效率)

      FILE=$1 
      TARGETROOT=$2
      
      grep '^[A-Z]*=' "$FILE2" | awk -F= '{print$1}' | while read PROP ; do
        find "$TARGETROOT" -type f | while read FILE2 ; do
          grep -l "^${PROP}=" "$FILE2" >/dev/null || {
            echo "Propery $PROP missing from $FILE2"
          }
        done
      done
      

    如果处理$TARGETROOT 下的大量属性和/或文件,您可以使用以下更有效的方法(它只打开和扫描每个文件一次,而不是之前解决方案的N 次,其中@987654335 @ 是 $FILE) 中的属性数:

    • 使用具有来自$FILE 的所有排序属性的临时文件以避免重复工作
    • 使用awk ... | sort -u 隔离出现在另一个文件$FILE2 中的所有排序属性
    • 使用comm -23 "$PROPSFILE" - 隔离那些仅出现在$PROPSFILE 中而不出现在标准输入中(即$FILE2)的行(属性)

      FILE=$1 
      TARGETROOT=$2
      
      PROPSFILE="/tmp/~props.$$"
      grep '^[A-Z]*=' "$FILE" | awk -F= '{print$1}' | sort -u >"$PROPSFILE"
      
      find "$TARGETROOT" -type f | while read FILE2 ; do
        grep '^[A-Z]*=' "$FILE2" | awk -F= '{print$1}' | sort -u |
        comm -23 "$PROPSFILE" - | while read PROP ; do
          echo "Propery $PROP missing from $FILE2"
        done
      done
      
      rm -f "$PROPSFILE"
      

    【讨论】:

    • 有时,grep+awk 可用于大文件。 grep 用于搜索模式,awk 用于处理。 grep的搜索算法更好。在您的 sed 脚本中,您正在进行替换,这是一项昂贵的操作。使用awk 分割字段要快得多。
    • 正确,并且假设$FILE 的大小不是兆字节,sed 才能有效工作。在这些情况下,将grepawk 组合成awk -F= '$1~/^[A-Z]*$/ && NF>1 { print $1 }' 会减少冗余。我更新了第二个示例以使用 awk 而不是 sed
    • 您甚至可以将sort -u | comm -23 ....|while.. 组合成awk ;)。减少 3 个管道进程。
    • 那可能有点过头了。 :) 现在我们摆脱了 sed 并且我们可以假设数兆字节的数据;)我不会开始在 awk 哈希中做 sortcomm 的工作——对于一个 sortcomm将在多核机器上完美扩展,比单个 awk 好得多。
    • 好吧,我不知道你从哪里得到这样的想法,即 awk 不会在多核机器上“完美地扩展”,但是在一个 awk 进程中完成所有工作肯定更有效。不要忘记 shell while read loop 当要迭代的数据很大时,这是一个主要的慢戳。 :)。无论如何,这将成为 OT,并且 +1 用于实际做一些全面的事情..:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多