Linux

從 ls 的輸出中獲取與模式匹配的數字?

  • July 17, 2018

我有一個文件夾,當我在其中執行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]+

有更好的方法來完成同樣的事情嗎?

解析的輸出ls是一個壞主意(的輸出ls嚴格用於查看)。有關這方面的更多資訊,請參閱問題“ Why not parse 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``$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

這將匹配並擷取t-每個文件名中的數字。${BASH_REMATCH[1]}成功匹配後,擷取的數字組可用。索引1引用正則表達式中的第一個擷取組(括號)。

對於緩慢但可能舒適(如“熟悉”)的解決方案,您可能需要呼叫外部命令來解析出您感興趣的字元串位:

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

這假設bash並且您可以cut在循環中呼叫。這比使用 shell 本身內置的操作要慢得多。這裡的命令被要求從傳遞給它的字元串cut中返回第二個-delimited 欄位(使用“here-string”重定向)。-``bash

引用自:https://unix.stackexchange.com/questions/456736