как обрезать имя файла таким образом, чтобы оно содержало только первое слово перед разделителем

Я пытаюсь получить имя пакета файлов 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), как в следующем примере

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

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

есть идеи, как получить только имя пакета, как указано выше?

-2
25.06.2020, 10:42
5 ответов

Во-первых, не разбиратьls. Вместо этого используйте globs:

$ 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

Обратите внимание, что это удалит все после первого -в пути. Поэтому, если у вас есть -перед именем пакета, вы можете получить неправильные результаты.

4
18.03.2021, 23:25

В одну сторону, без петли:

printf '%s\n' python/*.whl | cut -d'-' -f1
1
18.03.2021, 23:25

Два способа. :Используйте подстановку параметров, чтобы удалить бит имен файлов после первого тире в массиве, содержащем имена, или в каждом имени отдельно в цикле.

Использование массива:

$ 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из значения $variable. Оболочка bashтакже позволяет использовать эту замену для элементов массивов (, которую мы используем в первых вариантах выше ).

Чтобы получить тот же тип столбцов, что и 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
4
18.03.2021, 23:25

команда

ls /python/*.whl| awk -F "-" '{print $1}'

выход

/python/Jinja2
/python/MarkupSafe
/python/argparse
/python/certifi
/python/cffi
/python/chardet
/python/kazoo
/python/protobuf
1
18.03.2021, 23:25

Сzsh:

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

Или:

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

Или:

set -o histsubstpattern
print -rC1 /python/*-*.whl(N:s/-*//)
1
18.03.2021, 23:25

Теги

Похожие вопросы