Bash
如何以僅包含分隔符之前的第一個單詞的方式剪切文件名
我正在嘗試獲取 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