Bash

如何以僅包含分隔符之前的第一個單詞的方式剪切文件名

  • June 25, 2020

我正在嘗試獲取 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

任何想法如何僅獲取上述包名稱?

首先,不要解析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

請注意,這將刪除-路徑中第一個之後的所有內容。所以如果你-在包名之前有一個,你可能會得到錯誤的結果。

兩種方法:使用參數替換刪除包含名稱的數組上第一個破折號之後的文件名位,或者在循環中單獨刪除每個名稱。

使用數組:

$ 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。shell 也允許在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

引用自:https://unix.stackexchange.com/questions/594822