簡體   English   中英

關於使用 ORS、NR、FS、RS 的 awk 命令的說明

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM