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