1

再会!

我想知道如何打印以下输出的特定字母:

ls -1 *Mcmm*txt *Mmmm*txt

它给:

Mcmm_E.txt
Mcmm_M.txt
Mmmm_E.txt
Mmmm_M.txt

我想获得:

E
M
E
M

提前感谢您的任何建议

4

6 回答 6

2

您应该始终避免解析ls;看这里。改用find

find . -type f -name '*M[cm]mm*.txt' -print0

如果你有gnu grep,你可以输入:

grep -oPz '[^_](?=.txt)'

结果:

E
E
M
M
于 2013-11-09T00:34:57.890 回答
2

你可以试试这个。它基于_.作为分隔符打印最后一个字段(假设您需要打印最后一个_和之间的所有内容,.并假设.每个文件名中有一个实例)

ls -1 *Mcmm*txt *Mmmm*txt | awk -F'_|\\.' '{print $(NF-1)}'
于 2013-11-09T00:24:07.353 回答
2
ls -1 *Mcmm*txt *Mmmm*txt | cut -b6

打字比使用awk少很多...

cut -b6选择每行的第 6 个字节。

于 2013-11-09T00:30:37.730 回答
1

其他awk

ls -1 *Mcmm*txt *Mmmm*txt | awk -F"[_.]" '{print $2}'
E
M
E
M
于 2013-11-09T09:09:54.480 回答
1

不要解析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.

于 2013-11-09T10:28:32.327 回答
0
ls -1 *Mcmm*txt *Mmmm*txt | sed -u "s/^.\{5\}\(.\).*/\1/"

-u 用于流处理(避免在大文件夹上缓冲)

我认为cut会更快

在这种情况下,即使在 ls 中使用 *,您也不会处理第一个字符

于 2013-11-14T15:21:16.853 回答