【问题标题】:grep to find first content and second content of stringgrep 查找字符串的第一个内容和第二个内容
【发布时间】:2018-03-13 04:52:55
【问题描述】:

我有一个包含太多 shell 脚本代码的文件。在此,我有一个字符串“/usr/bin/rsync”,其输出如下

/usr/bin/rsync -arz --update --chmod=Du=rwx,Dg=rwx,Do=rwx,Fu=rwx,Fg=rw,Fo=rw -e "ssh -p 7887" root@192.168.1.201:/mnt/enjayvol1/remote/* /mnt/enjayvol5/esync/naspro/remote/ --bwlimit=0 --stats -h -l >> ${LOGFILE}

从这个字符串中,我想在第一次和第二次出现时找出当前存在的 enjayvol。

我需要输出,因为在上面的示例中,第一次出现的是 enjayvol1,第二次出现的是 enjayvol5

我需要使用两个命令

预期输出是 对于第一个命令 enjayvol1

第二个命令输出是 enjayvol5

我用过

firstcommand=`grep -w "/usr/bin/rsync" esync.sh  | grep -i enjayvol | head -1`

它将输出显示为

/usr/bin/rsync -arz --update --chmod=Du=rwx,Dg=rwx,Do=rwx,Fu=rwx,Fg=rw,Fo=rw /mnt/enjayvol1/lokesh/* -e "ssh -p 7887" root@192.168.1.201:/mnt/enjayvol5/esync/naspro/lokesh/ --bwlimit=0 --stats -h -l >> ${LOGFILE}

secondcommand=`grep -w "/usr/bin/rsync" esync.sh  | grep -i enjayvol | tail -1`

它显示输出为

/usr/bin/rsync -arz --update --chmod=Du=rwx,Dg=rwx,Do=rwx,Fu=rwx,Fg=rw,Fo=rw /mnt/enjayvol1/lokesh/* -e "ssh -p 7887" root@192.168.1.201:/mnt/enjayvol5/esync/naspro/lokesh/ --bwlimit=0 --stats -h -l >> ${LOGFILE}

【问题讨论】:

  • 不清楚你想要什么。你能发布一个更详细的例子吗? grep -m 1 '/usr/bin/rsync' "$filename.txt" | grep -om2 'enjayvol[[:digit:]]*' 之类的东西似乎与您所问的类似,但您的问题确实不清楚。
  • 我有 grep 'usr/bin/rsync' 现在在这个字符串中我想 grep enjayvol 在这个字符串中的第一次和第二次出现。在上面的示例输出中,第一次出现为 enjayvol1,第二次出现为 enjayvol5。我想要两个命令来找到这个
  • @DavidC.Rankin 请忽略这一行我已从我的问题中删除了这一行。
  • @LOKESH,请保持简单。添加示例输入并在帖子中而不是在 cmets 中添加带有条件的预期输出,以便我们可以尝试为您提供帮助。
  • 我已经编辑了我的问题

标签: bash sed grep cut


【解决方案1】:
$ awk -F'/' 'index($0,"/usr/bin/rsync") { for (i=1; i<=NF; i++) if ($i ~ /^enjayvol/) print $i }' file
enjayvol1
enjayvol5

【讨论】:

    【解决方案2】:

    sed 解决方案: 因此,您使用的是一个 shell 脚本,其中您将 grep 的输出放在 vars firstcommandsecondcommand 中。忽略在您的问题中两者具有相同值的事实,您正在寻找 rsync 的 srcdst。获得这些的另一种方法是使用 sed

    src=$(sed -E 's!.*(enjayvol(01?|1(01)?|5|6)).*(enjayvol(01?|1(01)?|5|6)).*!\1 \4!' \
     <<< $firstcommand | cut -d' ' -f1)
    

    对于 dst:

    dst=$(sed -E 's!.*(enjayvol(01?|1(01)?|5|6)).*(enjayvol(01?|1(01)?|5|6)).*!\1 \4!' \
     <<< $firstcommand | cut -d' ' -f2)
    

    您已经编辑了您的问题,放弃了 enjayvol-directorynames (0,1,01,10,11,5,6) 格式的要求,因此正则表达式可以简化为:

    src=$(sed -E 's!.*(enjayvol[0-9]).*(enjayvol[0-9]).*!\1 \2!' \
     <<< $firstcommand | cut -d' ' -f1)
    

    如有必要,您可以对 var secondcommand 执行相同操作。

    【讨论】:

      【解决方案3】:

      您能否尝试关注并让我知道这是否对您有帮助(您可以在单个命令本身中实现此目的)。以下答案将在一行中提供所有具有 enjayvol 的字符串。

      awk -v RS=" " '{match($0,/enjayvol[^/]*/);if(substr($0,RSTART,RLENGTH)){print substr($0,RSTART,RLENGTH)}}'  Input_file
      

      输出如下。

      enjayvol1
      enjayvol5
      

      编辑:如果您想搜索 /usr/bin/rsync 字符串,然后想获取字符串 enjaybol 的所有匹配项,那么以下内容可能会对您有所帮助。

      awk -v RS=" " '/${LOGFILE}/{val=""} /\/usr\/bin\/rsync/{val=1} val{match($0,/enjayvol[^/]*/);if(substr($0,RSTART,RLENGTH)){print substr($0,RSTART,RLENGTH)}}'  Input_file
      

      【讨论】:

      • 基本相同++。
      • @MarcLambrichs,我想我对 OP 有足够的 Q 和 A,并要求 OP 也提到完整的 Input_file,作为尝试,我已经发布了这个。让我们看看它对 OP 的影响。
      • @MarcLambrichs 有人问我如何用 X(Y) 做到这一点是很常见的,因为他只是不了解 Z。如果它是首选的话,一个好的答案会建议使用 Z解决方案和适用。
      • @RavinderSingh13 我在这里缺少的是搜索 /usr/bin/rsync
      • {match($0,/enjayvol[^/]*/);if(substr($0,RSTART,RLENGTH)){ = match($0,/enjayvol[^/]*/){
      【解决方案4】:

      grep 使用-o 开关(在下面的示例中,我使用了存储到文件file 中的grep 的输出。在现实世界中,您可以通过管道将输出从您的grep 到下面呈现的greps):

      $ grep -o enjayvol[^/]* file
      enjayvol1
      enjayvol5
      

      如果输入中的命中数超过 2,您可以使用 -m 2 开关将命中数限制为 2。

      再一次,如果字符串中存在例如benjayvol1(其中enjayvol 是一个子字符串),上述操作将失败。我们可以使用 PCRE 和 positive lookbehind(如果可用)来处理这个问题:

      $ grep -Po -m 2 "(?<=/)enjayvol[^/]*" file
      

      请参阅 man grep 以获取有关上述开关的更详尽说明。

      【讨论】:

        猜你喜欢
        • 2022-10-06
        • 2021-09-05
        • 2023-03-05
        • 1970-01-01
        • 2020-02-14
        • 2013-05-18
        • 2015-10-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多