grep 查找字符串的第一个内容和第二个内容

grep to find first content and second content of string

我有一个包含太多 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}

能否请您尝试关注并告诉我这是否对您有帮助(您可以通过单个命令本身实现)。以下答案将提供一行中包含 enjayvol 的所有字符串。

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

输出如下。

enjayvol1
enjayvol5

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

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

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

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

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

对于夏令时:

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

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

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

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

$ awk -F'/' 'index([=10=],"/usr/bin/rsync") { for (i=1; i<=NF; i++) if ($i ~ /^enjayvol/) print $i }' file
enjayvol1
enjayvol5