从 ls 的输出中获取与模式匹配的数字?

从 ls 的输出中获取与模式匹配的数字?

我有一个文件夹,当我ls在其中执行时,它输出

t-1-myFirstTest.c
myFile.c
t-42-my_second_test.c
t-3-test1234.c
  .
  .
  .
mySecondFile.c
t-21-tset241.c

我想删除该文本的所有内容,除了换行符以及t-和 第二个之间的数字-。所以前一个的输出应该是

1
42
3
 .
 .
 .
21

我有一个解决方案,但我认为这非常糟糕。如果我们正在讨论的文件夹实际上在当前目录中,那么我使用

ls | grep -o -E t-[0-9]+-[a-zA-Z0-9_]+.c | grep -o -E t-[0-9]+ | grep -o -E [0-9]+

有更好的方法来完成同样的事情吗?

答案1

解析 的输出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

这将迭代当前目录中名称与模式匹配的所有文件名t-*-*.c。对于每个名称,该t-位从一开始就被删除,然后第二个-以及之后的所有内容都通过另一个参数扩展被删除。

扩展将从中${variable#word}删除(最短)匹配word开始of $variable, while将从中${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

t-这将匹配并捕获每个文件名中后面的数字。${BASH_REMATCH[1]}成功匹配后,捕获的数字组即可使用。索引指1的是正则表达式中的第一个捕获组(括号)。

对于缓慢但可能舒适(如“熟悉”)的解决方案,您可能需要调用外部命令来解析您感兴趣的字符串位:

for filename in t-*-*.c; do
    [ ! -f "$filename" ] && continue
    cut -d '-' -f 2 <<<"$filename"
done

这假设bash您可以cut循环调用。这比使用 shell 本身内置的操作要慢得多。这里的命令被要求从传递给它的字符串中cut返回第二个分隔字段(使用“here-string”重定向)。-bash

答案2

根据你的输出:

ls|awk -F"-" '{print $2}'

应该可以,但是如果你想考虑这t-部分,那么

ls|grep ^t-|awk -F"-" '{print $2}'

或者

ls|awk -F"t-" '{print $2}'|awk -F"-" '{print $1}'

答案3

当我根据您的示例创建文件列表时,我以ls这种方式对它们进行排序:

$ ls -1
myFile.c
mySecondFile.c
t-1-myFirstTest.c
t-21-tset241.c
t-3-test1234.c
t-42-my_second_test.c

因此,下面的 bash 函数以相同的顺序输出文件的换行符和数字。

我想删除除换行符以及 t- 和第二个 - 之间的数字之外的所有文本

我对此的解释是,不匹配的文件名t-应该“删除,换行符除外”,意思是:为这些文件名输出一个空行,但否则输出破折号之间的数字。

lsnums ()
{
    for f in *
    do
        if [[ "$f" =~ t-([[:digit:]]+)- ]]; then
            printf '%s\n' "${BASH_REMATCH[1]}"
        else
            echo
        fi
    done
}

结果输出是:

$ lsnums


1
21
3
42

...其中两个空行对应于以my而不是开头的第一种类型文件t-

答案4

可以简单地通过以下方式完成:

ls | cut -d '-' -f 2

相关内容