簡體   English   中英

如何從awk或sed的行中提取單引號中的數字?

[英]how to extract number in a single quote from a line with awk or sed?

我有這行,以制表符分隔:

chr1    11460   11462   '16/38' 421     +       chr1    11460   11462   '21/29' 724     +       2
chr1    11479   11481   '11/29' 379     +       chr1    11479   11481   '20/5' 667     +       2

我要做的是測試''中的所有第二個數字是否都大於或等於10。如果是,我將輸出此行。 所以結果應該是打印第一行

chr1    11460   11462   '16/38' 421     +       chr1    11460   11462   '21/29' 724     +       2

我可以編寫一個perl代碼來做到這一點。 但這似乎是awk可以輕松完成的事情。任何人都有解決方案嗎?

謝謝。

如果設置正確的字段分隔符,則非常簡單:

awk -F "['/]" '{for (i=3; i<=NF; i+=3) if ($i<10) next; print}' file

獲取單引號內內容的最簡單方法可能只是剝離每一行兩端(包括單引號在內)的所有內容:

$ sed "s/^[^']*'//;s/'.*//" file
16/38
11/29

這個sed表達式包含兩個命令:

  • s/^[^']*'// -將所有文本剝離為第一個單引號,
  • s/'.*//將第一個(剩余的)單引號中的所有文本剝離到EOL。

要將其包裝在對數據執行某些操作的shell腳本中,需要..嗯,一個shell腳本...

您可以使用bash的read命令來解析這些內容。 例如:

#!/bin/bash
IFS=/
sed "s/^[^']*'//;s/'.*//" file \
| while read left right; do
  echo "$left / $right"
done

要實現可捕獲多個單引號內容的內容,可以適當地擴展sed腳本,並針對所需條件實現if語句。 例如,用於捕獲兩個單引號字符串的sed表達式可能是:

sed "s/^[^']*'\([^']*\)'[^']*'\([^']*\)'.*/\1 \2/"

這是一個大型正則表達式,它使用兩組括號\\(\\)來標記將放置在輸出中的模式\\1\\2

但是您最好根據列位置解析事物:

$ while read _ _ _ A _ _ _ _ _ B _; do echo "$A .. $B"; done < file
'16/38' .. '21/29'
'11/29' .. '20/5'

實際執行編程邏輯留給讀者練習。 如果您希望我們幫助您編寫腳本,請包括到目前為止的工作。

只要這些是字符串中唯一的'字符,並且數字不帶前導零,則可以使用正則表達式:

\d\d+'.*\d\d+'

如果這些先決條件中的任何一個都不成立,則可以進行更改,但要視情況而定。

您應該能夠使用grep來獲取要使用該正則表達式的行。 以下內容僅將第一行放入stdout:

grep \d\d+'.*\d\d+' "chr1    11460   11462   '16/38' 421     +       chr1    11460   11462   '21/29' 724     +       2
chr1    11479   11481   '11/29' 379     +       chr1    11479   11481   '20/5' 667     +       2"

我的版本,嚴重過大,但是每行可以使用任意數量的“ xx / xx”:

awk -F'\t' "{
    found=1;
    for(i=0;i<NF;i++){
        if(match(\$i, /'[[:digit:]]+\/([[:digit:]]+)'/, capts)){
            if(capts[1] < 10){
                found=0;
                break;
            }
        }
    }
    if(found){
        print;
    }
}" file.txt

說明:

這將遍歷該行的每個字段,並對該字段應用正則表達式以查找“ xx / xx”的最后一位。 如果最后一位少於10,它將跳出循環並轉到下一行。 如果if循環已經處理了所有字段,並且最后一位數字都不小於10,它將打印該行。

注意:

看到我正在使用match函數捕獲正則表達式組,這僅適用於GNU awk。

暫無
暫無

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

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