微妙的发现并替换为grep

时间:2018-10-08 11:29:55

标签: bash sed replace grep

我有一堆文件,所有文件都在同一目录中,名称分别为opening1.pyopening2.py ...,并且所有文件都带有'steps': [6]} ],行。我想做的是将6替换为9。我一直在这里尝试解决方案:How to grep and replace

使用这样的命令:

grep -rl "'steps': [6]} ]," opening* | xargs sed -i "s/'steps': [6]} ],/'steps': [9]} ],/g"

但是它不起作用。它说sed: no input files。我不知道问题是否是由于字符串或记号'中存在空格引起的。我该怎么办?

谢谢。

P。 S .:如果可能有帮助:文件opening...很大。我正在搜索的字符串位于for循环内,这也是一个很大且看起来很恐怖的循环:

for num in range(4):
    date_c = date_in
    while date_c <= date_in:
        lat = coordinates[num][0]
        lon = coordinates[num][1]
        df1 = gat.select_grib_df(inputfile,
                    {'indicatorOfParameter': 11},
                    [ {'coord': (lat, lon)],
                    'date': date_c,
                    'steps': [6]} ],
                    ['indicatorOfParameter', 'dataDate', 'dataTime', 'step'])

我希望与之前完全一样,但是steps中使用9而不是6:注意:有时indicatorOfParameter中的数字可以更改。

for num in range(4):
date_c = date_in
while date_c <= date_in:
    lat = coordinates[num][0]
    lon = coordinates[num][1]
    df1 = gat.select_grib_df(inputfile,
                {'indicatorOfParameter': 11},
                [ {'coord': (lat, lon)],
                'date': date_c,
                'steps': [9]} ],
                ['indicatorOfParameter', 'dataDate', 'dataTime', 'step'])

唯一的变化是单词steps中每9行中的数字6。

2 个答案:

答案 0 :(得分:1)

这可能是您想要的:

$ sed 's/\('\''steps'\'': \[\)6\(]} ],\)/\19\2/' file
'steps': [9]} ],

只需将其运行为:

sed -i 's/\('\''steps'\'': \[\)6\(]} ],\)/\19\2/' opening*

不需要grep。

提供更新的示例输入:

$ sed 's/\('\''steps'\'':[[:space:]]*\[\)6\(][[:space:]]*}[[:space:]]*][[:space:]]*,\)/\19\2/' file
for num in range(4):
    date_c = date_in
    while date_c <= date_in:
        lat = coordinates[num][0]
        lon = coordinates[num][1]
        df1 = gat.select_grib_df(inputfile,
                    {'indicatorOfParameter': 11},
                    [ {'coord': (lat, lon)],
                    'date': date_c,
                    'steps': [9]} ],
                    ['indicatorOfParameter', 'dataDate', 'dataTime', 'step'])

答案 1 :(得分:1)

Mac和BSD sed需要-i选项的参数。如果您要求脚本可移植到Linux / GNU sed,则可以将其重构为Perl。

sed -i '' "s/'steps': \[6\]} \],/'steps': [9]} ],/" opening*.py

在Perl中:

perl -pi -e "s/'steps': \[6\]\} \],/'steps': [9]} ],/" opening*.py

请注意,这两种方式都不使用grep -如果输入文件不包含匹配项,则将不会对其进行修改(尽管某些实现仍然会盲目地重写该文件并在此过程中更新时间戳)

还要注意,如何在正则表达式中转义方括号(在Perl中为大括号),以及如果您不希望单行出现多个匹配项,则/g标志是不必要的。 (只要正则表达式引擎之前没有未转义的],就可以容忍未转义的[。)

但是更好的解决方案是重构Python脚本,以便您可以将steps和任何其他参数(opening?)作为命令行参数来传递。

import sys

if len(sys.argv) == 1:
    # Should properly print to stderr, use logging?
    print('Syntax: opening.py <steps>')
    exit 1
steps_param = int(sys.argv[1])

for num in range(4):
    date_c = date_in
    while date_c <= date_in:
        lat = coordinates[num][0]
        lon = coordinates[num][1]
        df1 = gat.select_grib_df(
            inputfile,
            # indicatorOfParameter should apparently be refactored as well
            {'indicatorOfParameter': 11},
             [ {'coord': (lat, lon)],
                'date': date_c,
                'steps': [steps_param]} ],
             ['indicatorOfParameter', 'dataDate', 'dataTime', 'step'])