>我最近在 bash 脚本中遇到了以下行
sed -e :a -e '/^n*$/{$d;N;ba' -e '}' | sed -e '$s/,$/n/'
管道第一部分的输入由另一个管道给出,输入的形式为 1,2.3,2.453,23.5345,
相当的表达。让我们试着把它拆开。前几个命令是
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
这实际上可以被认为是 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
最后,我们在输入处没有空行。您可以使用末尾有空行的文件对此进行测试 - 您会发现当您通过脚本的第一部分运行它时,空行消失了。
现在让我们看一下第二个(更简单的)位:
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
换句话说,整个脚本似乎做到了:
删除输入末尾的所有空行,然后去除最后一行末尾不是空行的逗号并将其替换为换行符
注意:这不是对已发布问题的回答,因此不要接受它。这只是一个 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
$
在上面的RS=',n+$'
告诉awk整个文件中只有1条记录,它是最后一个逗号之前的所有内容,后跟1个或多个换行符。{print}
打印该记录,这本可以用'1'
完成,因为这是一个真实的条件,会调用打印当前记录的默认操作,但我试图强调简洁的清晰度部分而不是简洁性,因为我希望 OP 是一个新手。