web-dev-qa-db-ja.com

「-」の後のテキストを削除する方法は?

ファイルのリストがあります(基本的には.debパッケージです)。まあ言ってみれば:

abc-de-1.2.3-1.deb
fgh-ij-4.5.6-2.deb
klm-no-7.8.9-3.deb
pqrs-10.11.12-4.deb
...

ご覧のとおり、一部のファイル名には-の後に数字があり、他のファイル名には-の後にテキストがあり、次の-の後に数字があります。

-を含む数字から始まるすべてを削除する方法はありますか、つまり、

abc-de
fgh-ij
klm-no
pqrs
...

ファイルの名前を変更するのではなく、リストを編集します。

6
Raphael

最初の番号を使用して、毎回削除するものを特定できる場合は、次を使用できます。

$ sed 's/-[0-9].*//' file
abc-de
fgh-ij
klm-no
pqrs

ノート

  • s/old/new/oldnewに置き換えます
  • [0-9]数字
  • .*任意の数の任意の文字
8
Zanna

Perl正規表現でgrepを使用する:

$ grep -Po "^[a-z-]*(?=-[0-9])" filename
abc-de
fgh-ij
klm-no
pqrs
6
Ravexina

Perl

$ Perl -lne 's/([[:digit:]].*)//;s/-$//;print' input.txt                                                            
abc-de
fgh-ij
klm-no
pqrs

これは2つの置換を実行します。1つは数字で始まるすべてを削除し、末尾の-を削除します。 -iオプションを使用して、$ Perl -i -lne 's/([[:digit:]].*)//;s/-$//;print' input.txtなどの元のファイルを編集します

または、貪欲な非数字一致およびグループ化を使用する場合:

$ Perl -lne 's/^(\D*)-.*/\1/;print' input.txt                                                                                                        
abc-de
fgh-ij
klm-no
pqrs

AWK

$ awk -F '-' '{s=$1;for(i=2;i<=NF;i++) if($i~/[0-9].*/){print s;next}else{s=s"-"$i}}' input.txt 
abc-de
fgh-ij
klm-no
pqrs

これが機能する方法は、-をフィールドの区切り文字として扱い、各行を反復処理することです。最初のフィールドを「キャッシュ」し、forループを使用して反復処理を進めます。各反復で、列にs変数にパディングする数値が含まれていないかどうかを確認します。列に数字が含まれている場合-保存したものを印刷して、次の行に移動します。

最後に> new_file.txtを使用して、出力を新しいファイルにリダイレクトします。

Python

#!/usr/bin/env python
import sys,re

with open(sys.argv[1]) as f:
    for line in f:
        tokens = re.split("-|\.",line.strip().replace(".deb",""))
        words_only = filter(lambda x: not x.isdigit(),tokens)
        print("-".join(words_only))

re.split()を使用して、すべての行をトークンのリストに分割し、数字以外のトークンのみをフィルタリングします。

または、ここに1行のコマンドがあります。これは、行に数字がない場合の予防策ではないため、すべての行に数字が含まれていることが確実な場合にのみ使用してください。

$ python -c 'import re,sys;f=open(sys.argv[1]);print("\n".join([ l[:re.search(r"\d",l).start()-1] for l in f]))' input.txt

パッケージ名に含まれる可能性のある数字

hvdのコメントでは、パッケージ名に整数が含まれることがあり、入力ファイルの解析が困難になる場合がありますが、バージョン名には通常ドットが含まれていることが適切に記載されています。それを念頭に置いて、コマンドはそれを打ち消すためにいくらか変更することができます:

$ Perl -lne 's/\d*\..*//;s/-$//;print' input.txt

$ awk '{gsub(/[0-9]*\..*/,"");print substr($0,0,length($0)-1)};' input.txt                                                                           

$ python -c 'import re,sys;f=open(sys.argv[1]);print("\n".join([ l[:re.search(r"\d*\.",l).start()-1] for l in f]))' input.txt
4

Awkを通じて、

awk -F'-[0-9]' '{print $1}' file

Awkでは、フィールド区切り文字-Fへの引数として正規表現を渡すこともできます。そのため、正規表現が一致する部分で各行が分割されます。

例:

$ echo 'abc-de-1.2.3-1.deb' | awk -F'-[0-9]' '{print $1}'
abc-de
4
Avinash Raj

あなたはファイルがDEBパッケージであることを提案したので、推測するでしょう。

dpkg-query -f '${Package}\n' -W 'gnome*'

ここで、gnome*の代わりに、任意のパターンに置き換えることができます。 DEBアーカイブの命名規則が正確にはわからないが、もしそれらがDEBアーカイブであるなら、dpkgに依存してパッケージ名を与えるのがおそらく最善である。

そして、それらが(システム上の)DEBアーカイブファイルである場合、以下を使用できます。

dpkg-deb --showformat='${Package}\n' -W some-file.deb 
1
wvxvw