如何以仅包含分隔符之前的第一个单词的方式剪切文件名

如何以仅包含分隔符之前的第一个单词的方式剪切文件名

我正在尝试获取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

有什么想法如何只获取上面的包名称吗?

答案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

有两种方法: 使用参数替换来删除包含名称的数组上第一个破折号之后的文件名位,或者在循环中单独删除每个名称上的文件名位。

使用数组:

$ 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}删除最长可能的子字符串匹配。 shell也允许对数组元素使用这种替换(我们在上面的第一个变体中使用)。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/-*//)

相关内容