以下のコマンド出力からkim
、tin
および部分文字列のみを抽出するにはどうすればよいですか?tintu
単純な分割では部分文字列を取得できません-
。ビットxxx
は特定の演算子の文字列なので、ハッシュ処理します。
> kubectl get pods
xxxxxxxxxxxxxxx-x-ram-kdm-xxxxx-ramkim-6b4c49f589-6hqcj
xxxxxxxxxxxxxxx-x-ram-kdm-xxxxx-ramtin-8d49b4dc7-bmvck
xxxxxxxxxxxxxxx-x-ram-kdm-xxxxx-ramtintu-69b8c5b689-64fxw
申し訳ありません。クライアントの制限により、多くの情報を追加できません。出力の性格を説明します。 ramは、抽出する必要がある文字列に関連付けられた固定名です。各出力行の - の数は固定されておらず、文字もありません。この例では、ram は -ram- と表示されます。 ram + 'extract-string'が表示されるたびにリンクされた文字列を抽出するだけですが、一度だけ表示されます。
答え1
あなたのコメントに基づいて更新すると、これがあなたの要件を満たすと思います。
$ awk -F- '{
for (i=1;i<=NF;i++) {
if ($i ~ "^ram.+") { sub("^ram","",$i); print $i} }
}' kubectl.txt
kim
tin
tintu
英語:各入力行の各フィールドについて、フィールド値が正規表現^ram.+
(「ram」で始まり、次に続く)と一致する場合最後のものより多くの文字)その後、sub()を使用してフィールドの先頭から「ram」を削除し、フィールドを印刷します。
またはPerlでは:
$ perl -F- -lne 'foreach (@F) { print $1 if (m/^ram(.+)/) }' kubectl.txt
kim
tin
tintu
英語: 各行の各フィールドについて、フィールドが正規表現 "^ram(.+)" と一致する場合、サブ式に一致するフィールド(.+)
のキャプチャ部分 (たとえば "^ram" の後のすべての項目) を印刷します。
注:行の複数のフィールドがこのパターンと一致すると、すべて印刷されます。最初のフィールドだけが必要な場合は、現在のnext
行処理を停止して次の行に移動します。
awk -F- '{
for (i=1;i<=NF;i++) {
if ($i ~ "^ram.+") { sub("^ram","",$i); print $i; next } }
}' kubectl.txt
または
perl -F- -lne 'foreach (@F) { if (m/^ram(.+)/) { print $1; next } }' kubectl.txt
同様の質問をしている他の読者にはまだ役に立つかもしれません。
正確にどの出力が欲しいのか分からないので、ここにいくつかの可能性があります。両方とも、フィールド6($6
)がフィールド3()の内容で始まる行に対してのみ出力を生成します"^" $3
。他のすべての行は無視されます。
kubectl.txt
サンプル出力を含むテキストファイルkubectl get pods
。
フィールド6の部分文字列(文字4からフィールドの終わりまで):
$ awk -F- '$6 ~ "^" $3 { print substr($6,4) }' kubectl.txt
kim
tin
tintu
フィールド6の削除を使用して、最初からフィールド3の内容を削除しますsub()
。上記の例とは異なり、最初の3文字を削除するようにハードコードされていないため、$ 3の長さに関係なく機能します。
$ awk -F- '$6 ~ "^" $3 { sub("^" $3,"",$6); print $6}' kubectl.txt
kim
tin
tintu
上記のフィールド7と8と同じで、スペースで区切られています。
$ awk -F- '$6 ~ "^" $3 { sub("^" $3,"",$6); print $6, $7, $8}' kubectl.txt
kim 6b4c49f589 6hqcj
tin 8d49b4dc7 bmvck
tintu 69b8c5b689 64fxw
上記と同じですが、-
区切り記号があります。
$ awk -F- -vOFS=- '$6 ~ "^" $3 { sub("^" $3,"",$6); print $6, $7, $8}' kubectl.txt
kim-6b4c49f589-6hqcj
tin-8d49b4dc7-bmvck
tintu-69b8c5b689-64fxw
答え2
行の最後の「ram」の後に常に単語を表示したい場合は、すべての行の長さに対してこれを行います。
sed 's/.*ram\(\w\+\).*/\1/' your_file
仕組みは次のとおりです。
- 最後に、「ラム」が表示されるまですべてを検索しました。
.*ram
\(
上記を使ったことを覚えています。\)
- この場合、1つ以上の単語文字になります。
\w\+
- 残りの行と一致
.*
- それから覚えているものに変えてください。
\1
必要に応じて動作していることを確認したら、-i
ファイルを直接変更するには、次の項目を追加します。
sed -i 's/.*ram\(\w\+\).*/\1/' your_file
明確に言えば、上記の内容は次のとおりです。
xxxxxxxxxxxxxxx-x-ram-kdm-xxxxx-ramkim-6b4c49f589-6hqcj
xxxxxxxxxxxxxxx-x-ram-kdm-xxxxx-ramtin-8d49b4dc7-bmvck
xxxxxxxxxxxxxxx-x-ram-kdm-xxxxx-ramtintu-69b8c5b689-64fxw
以下を入力してください:
kim
tin
tintu
答え3
取得したいものが投稿の例にあるkim
、および文字列だけである場合は、tin
次のコマンドを使用して実行できます。tintu
cut -c 36- | sed "s/-.*//"
以下はいくつかの例です。
echo "xxxxxxxxxxxxxxx-x-ram-kdm-xxxxx-ramtintu-69b8c5b689-64fxw" | cut -c 36- | sed "s/-.*//"
出力:tintu
投稿の入力内容を含むファイルの場合:
cat file | cut -c 36- | sed "s/-.*//"
出力:
kim
tin
tintu
これは明らかですが、36
文字列に常に目的の文字列の前に文字がある場合にのみ機能します。
答え4
以下のコマンドが出力を提供する列
awk -F "-" '{for(i=1;i<=NF;i++){if($i ~ /kim|tin|tintu/){print substr($i,4)}}}' filename
出力
kim
tin
tintu