如何使用 sed 减少(减去)文件中的数字

moz*_*ozz 0 unix bash sed

我有一些源代码,如下所示,我在其中调用函数C

void myFunction (
    &((int) table[1, 0]),
    &((int) table[2, 0]),
    &((int) table[3, 0])
);
Run Code Online (Sandbox Code Playgroud)

...唯一的问题是该函数有 >300 个参数(它是一个自动生成的包装器,用于初始化和调用整个模块;它是给我的,我无法更改它)。1正如您所看到的:我开始使用 a而不是 a 来访问数组0来访问数组...伟大的时光,修改了所有 300 个参数,即手动减少 300 x 数组的 x 坐标。

我正在寻找的解决方案是我如何强迫sed为我做这项工作;)

编辑:请注意,上面在 C 中访问二维数组的语法无论如何都是错误的!当然应该是[1][0]......(所以不要只是复制粘贴;))

moz*_*ozz 5

基本上,我想出的命令如下:

sed -r 's/(.*)(table\[)([0-9]+)(,)(.*)/echo "\1\2$((\3-1))\4\5"/ge' inputfile.c > outputfile.c
Run Code Online (Sandbox Code Playgroud)

嗯,乍一看这看起来不太直观——而且我发现的几乎每个例子都缺少很好的解释。

所以我会尝试对此进行详细解释:

sed
Run Code Online (Sandbox Code Playgroud)

--> 基本命令

-r
Run Code Online (Sandbox Code Playgroud)

--> 您发现的大多数示例都使用-e; 但是,该-r参数(仅适用于 GNU sed)启用扩展正则表达式并带来对+正则表达式中的支持。它的基本意思是“一场或多场比赛”。

's/input/output/ge'
Run Code Online (Sandbox Code Playgroud)

--> 这是基本的替换语法。它的基本意思是“用‘输出’替换‘输入’”。这/g是一个“全局”标志,即 sed 将替换所有出现的情况,而不仅仅是第一个。您可以添加一个附加项e以在 bash 中执行结果。这就是我们想要在这里执行的计算。

(.*)
Run Code Online (Sandbox Code Playgroud)

--> 这匹配从上一场比赛到下一场比赛的“所有内容”

(table\[)
Run Code Online (Sandbox Code Playgroud)

-->\是为了转义括号。表达式的这一部分将匹配字符串,例如table[

([0-9]+)
Run Code Online (Sandbox Code Playgroud)

--> 这个匹配至少一位数字的数字,但是,它也可以匹配多于一位数字的更高数字。

(,)
Run Code Online (Sandbox Code Playgroud)

--> 这只是匹配逗号,

(.*)
Run Code Online (Sandbox Code Playgroud)

--> 再次:该行的其余部分

现在有趣的部分是:

echo "\1\2$((\3-1))\4\5"
Run Code Online (Sandbox Code Playgroud)
  • echo 是一个 bash 命令
  • \n您可以使用从\1到 的每个值\9)是输入的某种“变量”:\1将包含第一个匹配项,\2第二个匹配项,... --> 这可以帮助您保留输入字符串的部分内容
  • $((1+1))是一个简单的 bash 语法,用于计算双括号内术语的值(在sed上面的完整命令中,\3当然会自动替换为第三个匹配项,即括号内访问表格单元格的第一个部分)
  • 请注意,我们在回显内容周围使用引号,以便也能够处理带有此类字符的行,&否则这些字符将无法工作

最后已经提到e的将会触发 bash 中结果的执行。\ge例如,问题中示例源代码的前两行将生成以下 bash 语句:

echo "void myFunction ("
echo "    &((int) table[$((1-1)), 0]),"
Run Code Online (Sandbox Code Playgroud)

正在执行并产生以下输出:

void myFunction (
    &((int) table[0, 0]),
Run Code Online (Sandbox Code Playgroud)

...这正是我想要的:)

顺便说一句:text > output.c 是简单的 bash 语法,用于将text(或在本例中sed为处理后的源代码)输出到名为output.c.


关于该主题的良好链接是:

啊,还有一件事:您也可以sedgit-BashWindows 上使用 - 如果您像我一样“被迫”在工作中使用 Windows ;)

PS:与此同时,我可以轻松地手动完成此操作,但使用 sed 更有趣;)