bash脚本中使用的以下sed行的含义

3 regex linux bash sed

我最近在bash脚本中遇到了以下行

sed -e :a -e '/^\n*$/{$d;N;ba' -e '}' | sed -e '$s/,$/\n/'
Run Code Online (Sandbox Code Playgroud)

输入到管道的第一部分由另一个管道给出,输入是表格 1,2.3,2.453,23.5345,

Flo*_*ris 6

相当的表达.让我们尝试分开.前几个命令是

sed -e     invokes `sed` with the `-e` flag: "expression follows"
:a         a label - can be used with a branch statement (think "goto")
'/\n*$/    any number of carriage returns followed by end of string
{$d;N;ba'  delete the last line; next; branch to label a
-e '}'     close the bracket
Run Code Online (Sandbox Code Playgroud)

这实际上可以被认为是sed脚本文件的一行等价物:

:a         # label a 
{          # start of group of commands
/\n*$/     # select a line that has carriage returns and then end of string
           #(basically empty lines at end of file)
$d;        # delete the last line ($ = last line, d = delete)
N;         # next
ba         # branch to a
}          # end of group of commands
Run Code Online (Sandbox Code Playgroud)

在这结束时,我们在输入处没有留下空行.您可以使用末尾有空行的文件对此进行测试 - 您会发现当您通过脚本的第一部分运行它时,空行消失了.

现在让我们看看第二个(更简单)位:

sed -e     invoke sed on the output of the previous command
'$s        substitute in the last line
/,$/\n/    a comma before the end of the line with a newline
Run Code Online (Sandbox Code Playgroud)

换句话说,整个脚本似乎做:

删除输入末尾的所有空行,然后在最后一行不是空行的末尾删除逗号,并用换行符替换它


Ed *_*ton 5

注意:这不是已发布问题的答案,因此请勿接受它。这只是发布的 awk 脚本,用于与问题中发布的 sed 脚本进行比较,以获得一些额外的见解/信息。

假设 @Floris 对他认为脚本的作用是正确的,这是使用 GNU awk 执行此操作的一种方法。输入文件有几行数据,然后是 2 个空行:

$ cat file
1,2.3,2.453,23.5345,
1,2.3,2.453,23.5345,


$
$ gawk -v RS=',\n+$' '{print}' file
1,2.3,2.453,23.5345,
1,2.3,2.453,23.5345
$
Run Code Online (Sandbox Code Playgroud)

上面RS=',\n+$'告诉 awk 整个文件中只有 1 条记录,并且是最后一个逗号之前的所有内容,后跟 1 个或多个换行符。打印{print}记录,这本来可以完成'1',因为这是一个真实的条件,会调用打印当前记录的默认操作,但我试图强调这一点中简洁性而不是简洁性的清晰部分,因为我期望OP 是 awk 的新手。