次のデータを含むファイルがあります。
"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
|
抽出したい文字列の前に文字列があるかどうかを検索して確認します。- 同様に、抽出する文字列の後に次のものがあるかどうかを
(?=\|)
事前に確認してください。|
- 同様に、抽出する文字列の後に次のものがあるかどうかを
[^|]+
抽出する文字列 -|
その文字を1つ以上反転して取得します。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ハッシュを使用して一意性を確保できます。
$ 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
答え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)
}