我有一个样本数据集:
1
2
3
4
5
6
通过以下awk命令成功解析为所需的输出
awk 'ORS=NR%3?FS:RS'
1 2 3
4 5 6
能否请您说明此命令的作用?我无法将各个部分放在一起。
据我了解:
ORS
=输出记录分隔符-这就是我们希望RS成为最终输出的结果,它是3列的行
NR%3
=我们想将数据分组为3个元素的行
?FS:RS
-不确定它是否适合命令。
谢谢。
答案 0 :(得分:5)
Public Sub SetRangeNames(startRow As Integer, endRow As Integer)
Dim currentRow As Long 'Long not Integer (always safer)
For currentRow = startRow To endRow
With ThisWorkbook.Sheets("SYSProjectData")
'worksheets Parent is the containing workbook
.Parent.Names.Add Name:=.Cells(currentRow, "D"), _
RefersTo:=.Cells(currentRow, "C")
End With
Next currentRow
End Sub
是模运算符(请参见https://en.wikipedia.org/wiki/Modulo_operation),而%
是三元表达式(请参见https://en.wikipedia.org/wiki/%3F:)。这些都是许多编程语言中的常见构造,它们并非特定于awk。有关ORS,NR,FS和RS的含义,请参见awk手册页。
运行此命令,以在执行命令之前和之后查看代码中变量的值:
NR%3?FS:RS
。
$ cat tst.awk
BEGIN {
printf "%s=\"%s\"\n", "RS", RS
printf "%s=\"%s\"\n", "FS", FS
}
{
printf "---\n"
printf "%s=\"%s\"\n", "$0", $0
printf "%s=\"%s\"\n", "NR", NR
printf "%s=\"%s\"\n", "NR%3", NR%3
printf "before) %s=\"%s\"\n", "ORS", ORS
ORS = (NR%3 ? FS : RS)
printf "after) %s=\"%s\"\n", "ORS", ORS
}
请注意,输出记录分隔符($ awk -f tst.awk file
RS="
"
FS=" "
---
$0="1"
NR="1"
NR%3="1"
before) ORS="
"
after) ORS=" "
---
$0="2"
NR="2"
NR%3="2"
before) ORS=" "
after) ORS=" "
---
$0="3"
NR="3"
NR%3="0"
before) ORS=" "
after) ORS="
"
---
$0="4"
NR="4"
NR%3="1"
before) ORS="
"
after) ORS=" "
---
$0="5"
NR="5"
NR%3="2"
before) ORS=" "
after) ORS=" "
---
$0="6"
NR="6"
NR%3="0"
before) ORS=" "
after) ORS="
"
)在哪个输入行号(NR
)变为换行符(如ORS
)与空白字符(如RS
)之间
编写相同代码的更详细的方法是:
FS
并且仅供参考,编写在您的问题中尝试过的简洁,惯用代码的正确方法(更强大,更清晰)是:
$ cat tst.awk
{
if (NR%3 == 0) {
ORS = "\n"
}
else {
ORS = " "
}
print
}
$ awk -f tst.awk file
1 2 3
4 5 6
在某些情况下,在某些情况下需要三进制周围的括号,并且始终会提高可读性,因此请始终使用它们。原始代码依赖于分配给ORS的结果,该结果产生一个非空/非零值,以便使其成为真实条件,因此调用打印当前记录的awks默认动作。仅在需要时才在该上下文中使用操作的结果,否则有一天您的数据可能与您的预期不符时会咬住您。我没有将分配留在条件块中,而是将其移到动作块中,然后在其后添加了一个恒定的true条件,awk '{ORS=(NR%3?FS:RS)}1'
以确保打印每条记录,无论分配结果如何。
答案 1 :(得分:0)
对于每3条记录(NR-记录数),三元运算符的输出为0
。
这意味着满足0
的第二个条件。
cond ? non-zero : zero
因此,RS
被满意并且记录被分隔了-在这里用换行符,否则它是FS
字段分隔的
答案 2 :(得分:0)
不是awk
的解释,因为您已经有了多个答案,但是可以替代同一任务
$ seq 6 | xargs -n3
1 2 3
4 5 6
$ seq 6 | paste - - -
1 2 3
4 5 6
带有paste
的默认定界符是制表符,您可以使用-d' '
更改为空格
$ seq 6 | pr -3ats' '
1 2 3
4 5 6