簡體   English   中英

如何使用awk打印特定數字后的所有列?

[英]How to print all the columns after a particular number using awk?

在 shell 上,當我需要特定的列時,我會通過管道傳輸到 awk。

這將打印第 9 列,例如:

... | awk '{print $9}'

我如何告訴 awk 打印所有列,包括第 9和之后的所有列,而不僅僅是第 9 列?

awk '{ s = ""; for (i = 9; i <= NF; i++) s = s $i " "; print s }'

當您想要處理一系列字段時, awk並沒有真正直接的方法來執行此操作。 我會推薦cut代替:

cut -d' ' -f 9- ./infile

編輯

由於默認為制表符,因此添加了空格字段分隔符。 感謝格倫指出這一點

awk '{print substr($0, index($0,$9))}'

編輯:注意,如果第九個之前的任何字段包含與第九個相同的值,這將不起作用。

sed -re 's,\s+, ,g' | cut -d ' ' -f 9-

不是處理可變寬度的空格,而是將所有空格替換為單個空格。 然后對感興趣的領域使用簡單的cut

它不使用 awk,所以不是密切相關的,但考慮到其他答案/評論,它似乎是合適的。

通常 perl 替換 awk/sed/grep 等。 人,而且是便攜(以及剛剛成為一個更好的小刀)。

perl -lane 'print "@F[8..$#F]"'

Timtowtdi 當然適用。

awk -v m="\x01" -v N="3" '{$N=m$N ;print substr($0, index($0,m)+1)}'

這會截斷給定字段 nr., N 之前的內容,並打印該行的所有其余部分,包括字段 nr.N 並保持原始間距(不會重新格式化)。 字段的字符串是否也出現在行中的其他地方並不重要,這是 Ascherer 的答案的問題。

定義一個函數:

fromField () { 
awk -v m="\x01" -v N="$1" '{$N=m$N; print substr($0,index($0,m)+1)}'
}

並像這樣使用它:

$ echo "  bat   bi       iru   lau bost   " | fromField 3
iru   lau bost   
$ echo "  bat   bi       iru   lau bost   " | fromField 2
bi       iru   lau bost   

輸出保留所有內容,包括尾隨空格 對於 N=0,它按原樣返回整行,對於 n>NF 則返回空字符串

這是ls -l輸出的示例:

-rwxr-----@ 1 ricky.john  1493847943   5610048 Apr 16 14:09 00-Welcome.mp4
-rwxr-----@ 1 ricky.john  1493847943  27862521 Apr 16 14:09 01-Hello World.mp4
-rwxr-----@ 1 ricky.john  1493847943  21262056 Apr 16 14:09 02-Typical Go Directory Structure.mp4
-rwxr-----@ 1 ricky.john  1493847943  10627144 Apr 16 14:09 03-Where to Get Help.mp4

我打印$9后任何內容的解決方案是awk '{print substr($0, 61, 50)}'

使用 cut 而不是 awk 並解決了使用 -c 字符 cut 命令確定從哪一列開始的問題。

我的意思是,給我輸出的前 49 個字符以外的所有字符。

 ls -l /some/path/*/* | cut -c 50-

ls 命令末尾的/*/*/表示也顯示子目錄中的內容。

您還可以拉出某些范圍的字符 ala(來自剪切手冊頁)。 例如,顯示當前登錄用戶的姓名和登錄時間:

       who | cut -c 1-16,26-38

要顯示前 3 個字段並打印剩余的字段,您可以使用:

awk '{s = ""; for (i=4; i<= NF; i++) s= s $i : "; print $1 $2 $3 s}' filename

其中 $1 $2 $3 是前 3 個字段。

function print_fields(field_num1, field_num2){
    input_line = $0

    j = 1;
    for (i=field_num1; i <= field_num2; i++){
        $(j++) = $(i);

    }
    NF = field_num2 - field_num1 + 1;
    print $0

    $0 = input_line
}

通常希望通過未修改的剩余列。 也就是說,不會折疊連續的空白區域。

想象一下處理ls -lps faux輸出的情況(不推薦,僅舉例說明最后一列可能包含空格序列))。 我們希望保留剩余列中的任何連續空白,以便名為my file.txt的文件不會成為my file.txt

使用awk為行的其余部分保留空白非常困難。 即使有建議的改進,接受的基於 awk 的答案也沒有。

sedperl更適合此任務。

sed

echo '1 2 3 4 5 6 7 8 9   10' | sed -E 's/^([^ \t]*[ \t]*){8}//'

結果:

9   10

-E選項啟用現代 ERE 正則表達式語法。 這為我省去了反斜杠轉義括號和大括號的麻煩。

{8}是一個量詞,表示與前一項精確匹配 8 次。

sed s命令用空字符串替換 8 次出現的以空格分隔的單詞。 該行的其余部分保持不變。

perl

Perl 正則表達式支持水平空白的\\h轉義。

echo '1 2 3 4 5 6 7 8 9   10' | perl -pe 's/^(\H*\h*){8}//'

結果:

9   10
ruby -lane 'print $F[3..-1].join(" ")' file

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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