区切り文字の前の最初の単語のみを含めるようにファイル名を切り捨てる方法

区切り文字の前の最初の単語のみを含めるようにファイル名を切り捨てる方法

whlファイルのパッケージ名を取得しようとしています。

これらのファイルは

ls  /python/*.whl
/python/argparse-1.4.0-py2.py3-none-any.whl                   /python/Jinja2-2.11.2-py2.py3-none-any.whl
/python/certifi-2019.9.11-py2.py3-none-any.whl                /python/kazoo-2.2.1-py2.py3-none-any.whl
/python/cffi-1.14.0-cp27-cp27mu-manylinux1_x86_64.whl         /python/MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_x86_64.whl
/python/chardet-3.0.4-py2.py3-none-any.whl                    /python/protobuf-3.0.0-py2.py3-none-any.whl

-..........whl次の例のように、予想される出力は(none)でなければなりません。

  ls  /python/*.whl | SOME SYNTAX ......

    /python/argparse      /python/Jinja2
    /python/certifi      /python/kazoo
    /python/cffi         /python/MarkupSafe
    /python/chardet     /python/protobuf

上記のパッケージ名だけを取得する方法についてのアイデアはありますか?

答え1

まず、解析されないls。代わりにglobを使用してください。

$ for f in /python/*.whl; do printf '%s\n' "${f//-*}"; done
/python/argparse
/python/certifi
/python/cffi
/python/chardet
/python/Jinja2
/python/kazoo
/python/MarkupSafe
/python/protobuf

-これにより、パスの最初の項目以降のすべての内容が削除されます。したがって、-パッケージ名の前に置くと誤った結果が得られます。

答え2

2つの方法があります。パラメータ置換を使用して、名前を含む配列の最初のダッシュの後にあるファイル名ビットを削除するか、ループから各名前のファイル名ビットを個別に削除します。

配列を使用して下さい:

$ names=( /python/*-*.whl )
$ printf '%s\n' "${names[@]%%-*}"
/python/Jinja2
/python/MarkupSafe
/python/argparse
/python/certifi
/python/cffi
/python/chardet
/python/kazoo
/python/protobuf

または、名前付き配列の代わりに位置引数を使用します。

set -- /python/*-*.whl
printf '%s\n' "${@%%-*}"

ループを使用してください。

$ for name in /python/*-*.whl; do printf '%s\n' "${name%%-*}"; done
/python/Jinja2
/python/MarkupSafe
/python/argparse
/python/certifi
/python/cffi
/python/chardet
/python/kazoo
/python/protobuf

私は、一致する名前に実際にファイル名を切り捨てるために使用できるダッシュが含まれていることを確認するために、/python/*-*.whlファイル名を一致させるパターンを使用しています。/python/*.whl

パラメーター置換は、値から${variable%%pattern}可能な限り長い部分文字列一致を削除する標準置換です。シェルはまた、配列要素へのこれらの置換を可能にします(上記の最初の変形で使用されています)。pattern$variablebash

生成された列と同じタイプの列を取得するには、ls結果名をパイプしますcolumn。たとえば、次のようになります。

$ for name in /python/*.whl; do printf '%s\n' "${name%%-*}"; done | column
/python/Jinja2           /python/certifi          /python/kazoo
/python/MarkupSafe       /python/cffi             /python/protobuf
/python/argparse         /python/chardet

答え3

一方向、ループなし:

printf '%s\n' python/*.whl | cut -d'-' -f1

答え4

そしてzsh

print -rC1 /python/*-*.whl(Ne['REPLY=${REPLY%%-*}'])

または:

() { print -rC1 "${@%%-*}"; } /python/*-*.whl

または:

set -o histsubstpattern
print -rC1 /python/*-*.whl(N:s/-*//)

関連情報