[英]Explanation about awk command using ORS, NR, FS, RS
我有一個樣本數據集:
1
2
3
4
5
6
通過以下 awk 命令成功解析為所需的 output
awk 'ORS=NR%3?FS:RS'
1 2 3
4 5 6
你能解釋一下這個命令的作用嗎? 我無法將各個部分放在一起。
據我了解:
ORS
= output 記錄分隔符 - 這是我們希望 RS 用於最終 output,即一行 3 列
NR%3
= 我們希望將數據分組為 3 個元素的行
?FS:RS
- 不確定這如何適合命令。
謝謝。
%
是模運算符(參見https://en.wikipedia.org/wiki/Modulo_operation )和NR%3?FS:RS
是三元表達式(參見https://en.wikipedia.org/wiki/%3F: )。 這些都是許多編程語言中的常見結構,它們並不特定於awk。 有關ORS,NR,FS和RS的含義,請參閱awk手冊頁。
運行此命令以查看正在執行的命令之前和之后代碼中的變量值:
$ 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="
"
請注意輸出記錄分隔符( ORS
)的輸入行號( NR
)變為換行符(如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
以及在你的問題中嘗試編寫簡潔,慣用代碼的正確(更強大和更清晰)的方法是:
awk '{ORS=(NR%3?FS:RS)}1'
在某些情況下,某些問題需要三元組周圍的問題,並始終提高可讀性,以便始終使用它們。 原始代碼依賴於賦予ORS的結果,產生非空/非零值,以使其成為真實條件,因此調用awks默認操作來打印當前記錄。 只有在您需要時才使用該上下文中的操作結果,否則當您的數據不完全符合預期時,它會在某一天咬你。 我沒有將賦值保留在條件塊中,而是將其移動到一個動作塊中,然后在之后添加一個常量的真實條件, 1
以確保每個記錄都被打印,而不管該賦值是什么。
對於每3條記錄(NR - 記錄號),三元運算符的輸出為0
。
這意味着滿足第二個條件0
。
cond ? non-zero : zero
因此RS
滿足並且記錄被分開 - 這里是換行符,否則它是FS
場分離的
不是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
如果記錄計數是 3 的倍數 (NR%3,= 0),則 output 記錄分隔符設置為默認記錄分隔符 (RS)。 這是換行符。 如果記錄計數不是 3 的倍數 (NR%3 == 0),則 output 記錄分隔符設置為默認字段分隔符 (FS),即空格。
如果滿足此條件(因為您正在執行分配,它總是如此)然后執行默認操作,即打印記錄。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.