Незаметное нахождение и замена grep - PullRequest
0 голосов
/ 08 октября 2018

У меня есть куча файлов, все они в одном каталоге с именами opening1.py, opening2.py ... и все они имеют строку (и) с 'steps': [6]} ],.Я хочу заменить 6 на 9.Я пробовал решение здесь: Как выполнить grep и заменить

такой командой:

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

, но она не работает.Это говорит sed: no input files.Я не знаю, если проблема связана с наличием пробелов в строке или галочки '.Как я могу это сделать?

Спасибо.

PS: На случай, если это поможет: файлы opening... довольно большие.Строка, которую я ищу, находится внутри цикла for, также большая и, по-видимому, ужасная:: Примечание : иногда число в 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'])

единственное изменение - это число 6 на 9 в строке со словом steps.

Ответы [ 2 ]

0 голосов
/ 08 октября 2018

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'])
0 голосов
/ 08 октября 2018

Это может быть то, что вы ищете:

$ 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'])
...