sed:如果检查文件中存在代码块,则在大量文件上用另一个代码块替换一大块代码
Posted
技术标签:
【中文标题】sed:如果检查文件中存在代码块,则在大量文件上用另一个代码块替换一大块代码【英文标题】:sed: replace a big block of code by another on a large number of files if the code block exists in the inspected files 【发布时间】:2021-11-15 01:38:57 【问题描述】:我有以下代码块:
# Block bias spectro + pshot and correlations
FISH_super_flat_GCsp[0:7,0:7] = FISH_EUCLID_GCsp_flat[0:7,0:7]
FISH_super_flat_GCsp[7:17,7:17] = FISH_EUCLID_GCsp_flat[7:17,7:17]
FISH_super_flat_GCsp[0:7,7:17] = FISH_EUCLID_GCsp_flat[0:7,7:17]
FISH_super_flat_GCsp[7:17,0:7] = FISH_EUCLID_GCsp_flat[7:17,0:7]
# Block bias photo and correlations
FISH_super_flat_XC[0:7,0:7] = FISH_EUCLID_XC_flat[0:7,0:7]
FISH_super_flat_XC[20:31,20:31] = FISH_EUCLID_XC_flat[10:21,10:21]
FISH_super_flat_XC[0:7,20:31] = FISH_EUCLID_XC_flat[0:7,10:21]
FISH_super_flat_XC[20:31,0:7] = FISH_EUCLID_XC_flat[10:21,0:7]
# Block I.A and correlations
FISH_super_flat_XC[17:20,17:20] = FISH_EUCLID_XC_flat[7:10,7:10]
FISH_super_flat_XC[0:7,17:20] = FISH_EUCLID_XC_flat[0:7,7:10]
如果它存在于文件中,我想用这个新块替换它,在大量 Python 文件中:
# Block bias spectro + pshot and correlations
FISH_super_flat_GCsp[0:7,0:7] = FISH_EUCLID_GCsp_flat[0:7,0:7]
FISH_super_flat_GCsp[7:17,7:17] = FISH_EUCLID_GCsp_flat[7:17,7:17]
FISH_super_flat_GCsp[0:7,7:17] = FISH_EUCLID_GCsp_flat[0:7,7:17]
FISH_super_flat_GCsp[7:17,0:7] = FISH_EUCLID_GCsp_flat[7:17,0:7]
# Block bias photo and correlations
FISH_super_flat_XC[0:7,0:7] = FISH_EUCLID_XC_flat[0:7,0:7]
FISH_super_flat_XC[17:31,17:31] = FISH_EUCLID_XC_flat[7:21,7:21]
FISH_super_flat_XC[0:7,17:31] = FISH_EUCLID_XC_flat[0:7,7:21]
FISH_super_flat_XC[17:31,0:7] = FISH_EUCLID_XC_flat[7:21,0:7]
我知道使用sed
可能是可能的(或者肯定是gsed
,因为我在zsh MacOS 11.3
),但我需要帮助,因为我只有一次可能的机会(这就是我要进行备份的原因包含所有要检查的 Python 文件的 director)。
我可以使用类似的命令:
find directory_to_replace/ -type f -name '*.py' -exec sed **UNKNOWN COMMAND** \;
我知道用 sed 替换单词或正则表达式(例如 sed -i 's/\(pattern1\)/pattern2/g
),但我不知道如何设法替换上面的大块代码。
也许我需要将这两个块放入文本文件并使用sed
替换处理,但这是我第一次需要做这种操作。
更新
鉴于@potong
完成的解决方案,我已将此命令放入脚本中,并将该命令包含在所有 Python 文件的循环中:
#!/bin/bash
for i in $(find . -type f -name '*.py'); do
echo $i
gsed -e '$p;e echo MATCH;cat matchFile;echo REPLACE;cat replaceFile' -e '$d' $i |\
gsed -Ez '':a;s/(.*)(.*\nMATCH\1REPLACE(.*))$/\3\2/;ta;s/MATCH\n.*//'
done
如您所见,我使用 GNU sed "gsed
" 因为我在 MacOS 11.6
上:
很遗憾,我收到以下错误:
./script_replacement_block_synthesis.sh: line 6: syntax error near unexpected token `.*'
./script_replacement_block_synthesis.sh: line 6: `gsed -Ez '':a;s/(.*)(.*\nMATCH\1REPLACE(.*))$/\3\2/;ta;s/MATCH\n.*//''
我该如何解决这个错误?
【问题讨论】:
它必须是sed
吗?使用其他东西,例如,使用python
。 how to manage to replace big blocks
基本上是一样的,只是你要读多行,然后用正则表达式匹配多行。 sed
很难,sed -z
更简单。 | of Python files by this new block :
顺便说一句,用它做一个 python 函数/库来缓解未来的变化不是更好吗?
编者注:如果text is provided as images,并且没有按请求修复,可以关闭删除。
【参考方案1】:
这可能对你有用(GNU sed):
sed -e '$p;e echo MATCH;cat matchFile;echo REPLACE;cat replaceFile' -e '$d' file |
sed -Ez ':a;s/(.*)(.*\nMATCH\1REPLACE(.*))$/\3\2/;ta;s/(.*)MATCH\n.*/\1/'
将匹配的内容放在matchFile
中,将替换内容放在replaceFile
中。
将匹配项和替换项附加到相关文件中,并将结果通过管道传递给另一个 sed 调用。
使用模式匹配,将matchFile与文件中的匹配匹配,并用replaceFile替换,重复直到失败。
最后从原始文件的末尾删除匹配和替换文件。
替代方案:
cat file <(echo MATCH) matchFile <(echo REPLACE) replaceFile |
sed -zE ':a;s/(.*)(.*MATCH\1REPLACE(.*))$/\3\2/;ta;s/(.*)MATCH.*/\1/'
或者:
cat file <(echo MATCH) matchFile <(echo REPLACE) replaceFile |
sed -E 'H;1h;$!d;x;:a;s/(.*)(.*MATCH\1REPLACE(.*))$/\3\2/;ta;s/(.*)MATCH.*/\1/'
【讨论】:
非常感谢!你能看看我上面的 UPDATE 我提到我得到的错误。问候 @youpilat13 似乎第二次 sed 调用开始了 ``以上是关于sed:如果检查文件中存在代码块,则在大量文件上用另一个代码块替换一大块代码的主要内容,如果未能解决你的问题,请参考以下文章
检查列是不是已存在,如果不存在,则在 sqlite 中更改表
如何查找多个文件、检查重复文件并用 bash、sed 脚本替换