shell中根據分隔符號過濾數據

shell中根據分隔符號過濾數據

我有一個包含數據的文件,如下所示:

"google1|yoo|dummy|yes|wow|/" + VARIABLE + "/"
"google2|hub|lab|dummy|yes|/" + VARIABLE + "/"
"google3|short|lab|yoo|/" + VARIABLE + "/"
"google4|hello|good-guy|bad-girl|lol|dummy|/" + VARIABLE + "/"
"google5|good-guy|a4-123|yoo|/" + VARIABLE + "/"
"google6|bad-girl|b4-124|hub|/" + VARIABLE + "/"

現在,我想取得分隔符號“|”之間的字串列表(管道)。

輸出應該是

yoo
dummy
yes
wow
hub
hello
good-guy
bad-girl
a4-123
b4-124
dummy
lol
short
lab

基本上,我想在分隔符號過濾器之後從字串列表中獲得唯一值。我嘗試使用 awk 作為

awk -F"|" '{gsub(/\).*/,"",$2);print $2}' file

但是,我得到了錯誤的數據。

答案1

如果您有grep選項pcre

$ grep -oP '\|\K[^|]+(?=\|)' ip.txt | sort -u
a4-123
b4-124
bad-girl
dummy
good-guy
hello
hub
lab
lol
short
wow
yes
yoo
  • -o只列印匹配的模式
  • -P使用 PCRE 正規表示式
  • \|\K正向後查找,看看|在我們要提取的字串之前是否存在
    • 類似地,(?=\|)正向前視查看要|提取的字串後面是否有
  • [^|]+要提取的字串 - 只需求反|並獲取一個或多個此類字符
  • sort -u獲得獨特的價值

如果您想保留這些字串的查找順序:

$ grep -oP '\|\K[^|]+(?=\|)' ip.txt | awk '!seen[$0]++'
yoo
dummy
yes
wow
hub
lab
short
hello
good-guy
bad-girl
lol
a4-123
b4-124

答案2

如果你不關心順序,你可以使用 perl hash 來確保唯一性,例如

$ perl -lne '$h{$_}++ for /(?<=\|).*?(?=\|)/g; END{print for keys %h}' file
short
b4-124
lol
yes
bad-girl
lab
yoo
good-guy
hub
dummy
hello
a4-123
wow

在 perl 中使用正規表示式匹配建立哈希

答案3

那麼以下呢?

cut file -d'|' -f2,3,4 | tr '|' '\n'

上述命令將列印固定數量的列 (3)。如果您想要列印可變數量的列,直到第一次出現/,您可以使用類似以下內容的內容:

cut -d'/' -f1 file | cut  -d'|' -f2- | tr '|' '\n'

答案4

您的輸出有“虛擬”重複。這就是我透過下面的腳本得到的結果——

   awk -f f1.awk /tmp/f1
    short
    hub
    wow
    hello
    a4-123
    b4-124
    yes
    yoo
    lol
    bad-girl
    good-guy
    lab
    dummy

    cat f1.awk 
    {
      n=split($1,a,"|")

      for(i=2; i<n; i++) {
        arr[a[i]] = a[i] 
      } 
    }   
    END{
      for (var in arr) 
        print(var)  
    }

相關內容