Gar*_*ain 5 linux ls bash filenames text-formatting
我有一个文件夹,当我ls
在其中执行时,它会输出
t-1-myFirstTest.c
myFile.c
t-42-my_second_test.c
t-3-test1234.c
.
.
.
mySecondFile.c
t-21-tset241.c
Run Code Online (Sandbox Code Playgroud)
我想删除此文本的所有内容,除了换行符和t-
第二个-
. 所以前一个的输出应该是
1
42
3
.
.
.
21
Run Code Online (Sandbox Code Playgroud)
我有一个解决方案,但我认为它真的很糟糕。如果我们所说的文件夹实际上在当前目录中,那么我使用
ls | grep -o -E t-[0-9]+-[a-zA-Z0-9_]+.c | grep -o -E t-[0-9]+ | grep -o -E [0-9]+
Run Code Online (Sandbox Code Playgroud)
有没有更好的方法来完成同样的事情?
解析 的输出ls
是一个坏主意( 的输出ls
严格用于查看)。有关详细信息,请参阅问题“为什么不*解析 `ls`? ”。
您可以按照以下方式进行操作/bin/sh
:
for filename in t-*-*.c; do
[ ! -f "$filename" ] && continue
number=${filename#t-} # remove "t-" from start of filename
number=${number%%-*} # remove everything from first "-" in what remains
printf '%s\n' "$number"
done
Run Code Online (Sandbox Code Playgroud)
这将迭代当前目录中名称与模式匹配的所有文件名t-*-*.c
。对于每个名称,该t-
位从一开始就被删除,然后第二个-
以及之后的所有内容都通过另一个参数扩展被删除。
扩展将从的开头${variable#word}
删除 (最短) 匹配,而从字符串末尾删除 (最长) 匹配。word
$variable
${variable%%word}
word
使用bash
,对文件名使用正则表达式匹配:
for filename in t-*-*.c; do
[ ! -f "$filename" ] && continue
if [[ "$filename" =~ ^t-([0-9]+)- ]]; then
printf '%s\n' "${BASH_REMATCH[1]}"
fi
done
Run Code Online (Sandbox Code Playgroud)
这将匹配并捕获每个文件名中后面的数字t-
。${BASH_REMATCH[1]}
成功匹配后,捕获的数字组即可使用。索引指1
的是正则表达式中的第一个捕获组(括号)。
对于缓慢但可能舒适(如“熟悉”)的解决方案,您可能需要调用外部命令来解析您感兴趣的字符串位:
for filename in t-*-*.c; do
[ ! -f "$filename" ] && continue
cut -d '-' -f 2 <<<"$filename"
done
Run Code Online (Sandbox Code Playgroud)
这假设bash
您可以cut
循环调用。这比使用 shell 本身内置的操作要慢得多。这里的命令被要求从传递给它的字符串中cut
返回第二个分隔字段(使用“here-string”重定向)。-
bash