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
的输出通过管道传输到下面显示的 grep
s):
$ 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 的输出放入变量 firstcommand 和 secondcommand 中。忽略在你的问题中两者具有相同值的事实,你正在寻找你的 rsync 的 src 和 dst 。获得这些的另一种方法是使用 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
我有一个包含太多 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
的输出通过管道传输到下面显示的 grep
s):
$ 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 的输出放入变量 firstcommand 和 secondcommand 中。忽略在你的问题中两者具有相同值的事实,你正在寻找你的 rsync 的 src 和 dst 。获得这些的另一种方法是使用 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