0

I have a lot of Jupyter notebooks that contain the following pattern

try:
    import tensorflow as tf
except:
    %pip install tensorflow
    import tensorflow as tf

According to pylint, I should provide a more specific exception object, i.e.

try:
    import tensorflow as tf
except ModuleNotFoundError:
    %pip install tensorflow
    import tensorflow as tf

That's the basic idea, but to be more precise, the notebooks are essentially JSON files, and they actually contain something like

"try:\n",
"    import tensorflow\n",
"except:\n",
"    %pip install tensorflow\n",
"    import tensorflow\n",

Since there are hundreds of notebooks, I cannot go over them manually, so I planned to do a find-and-replace with ag and sed, e.g.

ag -l '^"except:\\\\n",$' | xargs sed -i '' 's/except:/except ModuleNotFoundError:/g'

However, not all except: blocks contain %pip install statements. How can I replace all except: with except ModuleNotFoundError: only if it's followed by a %pip install?

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
nalzok
  • 14,965
  • 21
  • 72
  • 139

2 Answers2

2

Another option using sed might be:

sed '/except:/{N;/:\n[[:space:]]*%pip install/{s// ModuleNotFoundError&0/}}' file
  • When matching except:
  • Read (append) the next line to the pattern space using N
  • If the current pattern space matches :\n[[:space:]]*%pip install
  • Use the last matched pattern // and replace with ModuleNotFoundError followed by the full match &0

This pattern :\n[[:space:]]*%pip install matches the : a newline and optional spaces and then %pip install

Output

try:
    import tensorflow as tf
except ModuleNotFoundError:
    %pip install0 tensorflow
    import tensorflow as tf
The fourth bird
  • 154,723
  • 16
  • 55
  • 70
  • 1
    I got `sed: 1: "/except:/{N;/:\n[[:spac ...": bad flag in substitute command: '}'`. Presumably because I am on macOS, which bundles with BSD `sed`? **EDIT:** it works after I installed `gsed`! – nalzok May 03 '22 at 20:26
1

Using sed

$ sed '/except:/{N;/%pip install/{s/except:/except ModuleNotFoundError:/}}' input_file
try:
    import tensorflow as tf
except ModuleNotFoundError:
    %pip install tensorflow
    import tensorflow as tf
  • Match lines with except:
  • If the N; next line contains the string %pip install then
  • Match only the except: with %pip install as the next line and change it to except ModuleNotFoundError:
HatLess
  • 10,622
  • 5
  • 14
  • 32
  • Could you explain the command a little bit, e.g. why `except:` appears twice, so that I can adapt it to the JSON file? – nalzok May 03 '22 at 19:47
  • @nalzok Please check edit – HatLess May 03 '22 at 19:51
  • 1
    I got `sed: 1: "/except:/{N;/%pip insta ...": bad flag in substitute command: '}'`. Presumably because I am on macOS, which bundles with BSD `sed`? **EDIT:** it works after I installed `gsed`! – nalzok May 03 '22 at 20:26