使用shell脚本正则表达式(Using regular expressions in shell

2019-09-01 21:25发布

什么是解析使用在Linux shell脚本正则表达式的字符串的正确方法是什么? 我写了下面的脚本使用打印在控制台上我的SO代表curlsed (并不仅仅因为我是代表疯狂-我想切换到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组合。 当您需要更复杂的处理,将多达awkperl

我首先想到的是只使用:

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参数两个命令:

  • s/,//g用于去除所有逗号,尤其是那些存在于信誉值。

  • s/^.*reputation...\([0-9]*\).*$/\1/定位在该行的信誉值,并通过该值代替整条生产线。

在这种特殊情况下,我发现, sed提供了最紧凑的命令没有可读性的损失。

处理字符串(不只是正则表达式)其他工具包括:

  • grepawkperl大多数其他的答案中提到的
  • tr替换字符
  • cutpaste处理多列投入
  • bash本身以其丰富的$(...)用于访问变量的语法
  • tailhead保持文件的最后或第一线


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