我在sh (Mac OSX 10.6)中有这个小脚本来查看文件数组。谷歌在这一点上已经不再有用了:
files="*.jpg"
for f in $files
do
echo $f | grep -oEi '[0-9]+_([a-z]+)_[0-9a-z]*'
name=$?
echo $name
done
到目前为止(显然,对于shell专家来说)$name仅包含0,1或2,这取决于grep是否发现文件名与提供的问题匹配。我想要的是捕获parens ([a-z]+)内的内容并将其存储到一个变量中。
如果可能的话,我只想使用grep。如果不是,请不要使用Python或Perl等sed或类似的语言——我想从*nix纯粹的角度来攻击这个问题。
此外,作为一个超级酷的奖金,我很好奇我如何能在壳串?我捕获的组是存储在$name中的字符串“someename”,我想在它的末尾添加字符串“.jpg”,我可以cat $name '.jpg'吗?
这对于纯grep来说是不可能的,至少一般来说是不可能的。
但是,如果您的模式是合适的,您可以在管道中多次使用grep,首先将行缩减为已知格式,然后提取所需的部分。(尽管像cut和sed这样的工具在这方面做得更好)。
为了便于讨论,假设你的模式更简单一些:[0-9]+_([a-z]+)_你可以这样提取:
echo $name | grep -Ei '[0-9]+_[a-z]+_' | grep -oEi '[a-z]+'
第一个grep将删除与您的整体样式不匹配的任何行,第二个grep(指定了—only-matching)将显示名称的alpha部分。这只是因为模式是合适的:“alpha部分”足够具体,可以提取出您想要的内容。
(旁白:就我个人而言,我会使用grep + cut来实现你想要的:echo $name | grep {pattern} | cut -d _ -f 2。这将通过分隔符_将行解析为多个字段,并仅返回字段2(字段号从1开始)。
Unix的哲学是让工具做一件事,并做得很好,并结合它们来完成非平凡的任务,所以我认为grep + sed等是一种更Unix的做事方式:-)
我更喜欢一行的python或perl命令,这两者通常都包含在主要的linux发行版中
echo $'
<a href="http://stackoverflow.com">
</a>
<a href="http://google.com">
</a>
' | python -c $'
import re
import sys
for i in sys.stdin:
g=re.match(r\'.*href="(.*)"\',i);
if g is not None:
print g.group(1)
'
处理文件:
ls *.txt | python -c $'
import sys
import re
for i in sys.stdin:
i=i.strip()
f=open(i,"r")
for j in f:
g=re.match(r\'.*href="(.*)"\',j);
if g is not None:
print g.group(1)
f.close()
'
这对于纯grep来说是不可能的,至少一般来说是不可能的。
但是,如果您的模式是合适的,您可以在管道中多次使用grep,首先将行缩减为已知格式,然后提取所需的部分。(尽管像cut和sed这样的工具在这方面做得更好)。
为了便于讨论,假设你的模式更简单一些:[0-9]+_([a-z]+)_你可以这样提取:
echo $name | grep -Ei '[0-9]+_[a-z]+_' | grep -oEi '[a-z]+'
第一个grep将删除与您的整体样式不匹配的任何行,第二个grep(指定了—only-matching)将显示名称的alpha部分。这只是因为模式是合适的:“alpha部分”足够具体,可以提取出您想要的内容。
(旁白:就我个人而言,我会使用grep + cut来实现你想要的:echo $name | grep {pattern} | cut -d _ -f 2。这将通过分隔符_将行解析为多个字段,并仅返回字段2(字段号从1开始)。
Unix的哲学是让工具做一件事,并做得很好,并结合它们来完成非平凡的任务,所以我认为grep + sed等是一种更Unix的做事方式:-)