什么是解析使用在Linux shell脚本正则表达式的字符串的正确方法是什么? 我写了下面的脚本使用打印在控制台上我的SO代表curl
和sed
(并不仅仅因为我是代表疯狂-我想切换到Linux之前,学习一些shell脚本和正则表达式)。
json=$(curl -s http://stackoverflow.com/users/flair/165297.json)
echo $json | sed 's/.*"reputation":"\([0-9,]\{1,\}\)".*/\1/' | sed s/,//
但不知何故,我觉得sed
是不是在这里使用合适的工具。 我听说grep
是所有关于正则表达式,并探讨了一点。 但很显然,它打印每当找到匹配的整条生产线 - 我想从单个文本行提取数。 下面是我的工作字符串(通过返回的缩小版本curl
)。
{ “显示名”: “Amarghosh”, “信誉”: “2737”, “badgeHtml”: “\ u003cspan标题= \” 1银徽章\ “\ u003e \ u003cspan类= \” badge2 \“\ u003e● \ u003c /跨度\ u003e \ u003cspan类= \ “badgecount \” \ u003e1 \ u003c /跨度\ u003e \ u003c /跨度\ u003e“}
我想我的问题是:
- 什么是解析使用在Linux shell脚本正则表达式的字符串的正确方法是什么?
- 是
sed
在这里使用了正确的事情? - 难道这用做
grep
? - 是否有任何其他的命令,更容易/合适?
Answer 1:
的grep
命令将选择从许多期望的线(S),但它不会直接操纵线。 为此,您使用sed
的管道:
someCommand | grep 'Amarghosh' | sed -e 's/foo/bar/g'
可替代地, awk
(或perl
如果可用)都可以使用。 它比一个更强大的文本处理工具sed
在我看来。
someCommand | awk '/Amarghosh/ { do something }'
对于简单的文本操作,则只需使用grep/sed
组合。 当您需要更复杂的处理,将多达awk
或perl
。
我首先想到的是只使用:
echo '{"displayName":"Amarghosh","reputation":"2,737","badgeHtml"'
| sed -e 's/.*tion":"//' -e 's/".*//' -e 's/,//g'
其保持的数量sed
流程,以一个(可以给多个命令与-e
)。
Answer 2:
你可能有兴趣在使用Perl此类任务。 作为示范,这里是它打印您需要的号码一个Perl脚本:
#!/usr/local/bin/perl
use warnings;
use strict;
use LWP::Simple;
use JSON;
my $url = "http://stackoverflow.com/users/flair/165297.json";
my $flair = get ($url);
my $parsed = from_json ($flair);
print "$parsed->{reputation}\n";
这个脚本要求你安装了JSON模块,您可以只用命令做cpan JSON
。
Answer 3:
对于在shell脚本中使用JSON工作,使用jsawk其中如awk,但对于JSON。
json=$(curl -s http://stackoverflow.com/users/flair/165297.json)
echo $json | jsawk 'return this.reputation' # 2,747
Answer 4:
我的建议:
$ echo $json | sed 's/,//g;s/^.*reputation...\([0-9]*\).*$/\1/'
我把SED参数两个命令:
在这种特殊情况下,我发现, sed
提供了最紧凑的命令没有可读性的损失。
处理字符串(不只是正则表达式)其他工具包括:
-
grep
, awk
, perl
大多数其他的答案中提到的 -
tr
替换字符 -
cut
, paste
处理多列投入 -
bash
本身以其丰富的$(...)
用于访问变量的语法 -
tail
, head
保持文件的最后或第一线
Answer 5:
sed
是合适的,但对于每一个你会产生新的进程sed
使用(可能是太重量级比较复杂的情况)。 grep
是不是真的合适。 这是一个使用正则表达式查找感兴趣线搜寻工具。
Perl的是这里一个合适的解决方案,是一个shell脚本语言,具有强大的正则表达式的功能。 它会做不产卵出单独的进程(不像正常的Unix shell脚本),你最需要的一切,并有附加功能的巨大的图书馆。
Answer 6:
您可以使用grep做到这一点。 目前仅在匹配字符串不是整条生产线的grep巫提取-o开关。
$ echo $json | grep -o '"reputation":"[0-9,]\+"' | grep -o '[0-9,]\+'
2,747
Answer 7:
1)什么是解析使用在Linux shell脚本正则表达式的字符串的正确方法是什么?
工具,包括正则表达式的能力包括战略经济对话的grep,awk中,Perl,Python和仅举几例。 猛击即使新版本有正则表达式的能力。 所有你需要做的就是查找关于如何使用它们的文档。
2)是sed在这里使用了正确的事情?
它可以是,但不是必需的。
3)难道这用grep来完成?
是的,它可以。 你只会构建类似的正则表达式,你会如果你使用SED或其他。 需要注意的是grep的只是做它做什么,如果你想修改任何文件,也不会为你做。
4)是否有任何其他的命令,更容易/更合适呢?
当然。 正则表达式可以是强大的,但它不一定是最好的工具来使用每次。 这也取决于你所说的“容易/恰当”的内容。 另一种方法与正则表达式最小忙乱使用场/定界符方法使用。 你看可以“分裂”的模式。 对于例如,你的情况(我已经下载了165297.json文件,而不是使用curl。(但其相同)
awk 'BEGIN{
FS="reputation" # split on the word "reputation"
}
{
m=split($2,a,"\",\"") # field 2 will contain the value you want plus the rest
# Then split on ":" and save to array "a"
gsub(/[:\",]/,"",a[1]) # now, get rid of the redundant characters
print a[1]
}' 165297.json
输出:
$ ./shell.sh
2747
Answer 8:
sed
是你的任务一个完全有效的命令,但它可能不会是唯一的一个。
grep
可能是有用的太多,但正如你所说的它打印一整行。 这是用于过滤多行文件的行,并丢弃你不想线最有用的。
有效的shell脚本可以使用命令的组合(不只是你提到的两个),利用每个人才。
Answer 9:
一味地:
echo $json | awk -F\" '{print $8}'
类似(字段分隔符可以是一个正则表达式):
awk -F'{"|":"|","|"}' '{print $5}'
智慧(寻找钥匙,并打印其值):
awk -F'{"|":"|","|"}' '{for(i=2; i<=NF; i+=2) if ($i == "reputation") print $(i+1)}'
Answer 10:
您可以使用正确的库(如其他说明):
E:\Home> perl -MLWP::Simple -MJSON -e "print from_json(get 'http://stackoverflow.com/users/flair/165297.json')->{reputation}"
要么
$ perl -MLWP::Simple -MJSON -e 'print from_json(get "http://stackoverflow.com/users/flair/165297.json")->{reputation}, "\n"'
取决于OS /壳组合。
Answer 11:
通过壳牌简单的regex
不考虑问题特定的代码,有时可能当你想要做一个快速的正则表达式替换,所有从标准输入使用的外壳,以简单的方式,使用类似的JavaScript字符串语法到stdout。
下面是为寻找一种方式来做到这一点的一些例子。 Perl是在Mac上一个更好的选择,因为它缺乏一些SED选项。 如果你想获得标准输入,你可以使用一个变量MY_VAR=$(cat);
。
echo 'text' | perl -pe 's/search/replace/g'; # using perl
echo 'text' | sed -e 's/search/replace/g'; # using sed
而且这里有一个自定义的,可重复使用的正则表达式函数的例子。 参数是源字符串 (或-为标准输入), 搜索 , 替换 ,和选项 。
regex() {
case "$#" in
( '0' ) exit 1 ;; ( '1' ) echo "$1"; exit 0 ;;
( '2' ) REP='' ;; ( '3' ) REP="$3"; OPT='' ;;
( * ) REP="$3"; OPT="$4" ;;
esac
TXT="$1"; SRCH="$2";
if [ "$1" = "--" ]; then [ ! -t 0 ] && read -r TXT; fi
echo "$TXT" | perl -pe 's/'"$SRCH"'/'"$REP"'/'"$OPT";
}
echo 'text' | regex -- search replace g;
文章来源: Using regular expressions in shell script