再会!
我想知道如何打印以下输出的特定字母:
ls -1 *Mcmm*txt *Mmmm*txt
它给:
Mcmm_E.txt
Mcmm_M.txt
Mmmm_E.txt
Mmmm_M.txt
我想获得:
E
M
E
M
提前感谢您的任何建议
您应该始终避免解析ls
;看这里。改用find
:
find . -type f -name '*M[cm]mm*.txt' -print0
如果你有gnu grep
,你可以输入:
grep -oPz '[^_](?=.txt)'
结果:
E
E
M
M
你可以试试这个。它基于_
和.
作为分隔符打印最后一个字段(假设您需要打印最后一个_
和之间的所有内容,.
并假设.
每个文件名中有一个实例)
ls -1 *Mcmm*txt *Mmmm*txt | awk -F'_|\\.' '{print $(NF-1)}'
ls -1 *Mcmm*txt *Mmmm*txt | cut -b6
打字比使用awk少很多...
cut -b6
选择每行的第 6 个字节。
其他awk
ls -1 *Mcmm*txt *Mmmm*txt | awk -F"[_.]" '{print $2}'
E
M
E
M
不要解析ls
. 在您的特定情况下,如果您只想打印与您的模式匹配的每个文件名的第六个字符,请执行以下操作:
files_ary=( *Mcmm*txt *Mmmm*txt )
for f in "${files_ary[@]}"; do
printf '%s\n' "${f:5:1}"
done
只打印 前面的字符.txt
,一个有趣的可能性是:
files_ary=( *Mcmm*.txt *Mmmm*.txt )
for f in "${files_ary[@]%.txt}"; do
printf '%s\n' "${f: -1}"
done
这些方法是 100% 纯 bash,即使文件名中有有趣的符号(空格、换行符等),它们也可以工作。哦,为了 100% 安全,不要忘记将 glob 与shopt -s nullglob
.
ls -1 *Mcmm*txt *Mmmm*txt | sed -u "s/^.\{5\}\(.\).*/\1/"
-u 用于流处理(避免在大文件夹上缓冲)
我认为cut
会更快
在这种情况下,即使在 ls 中使用 *,您也不会处理第一个字符