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-개행 문자와 와 second 사이의 숫자를 제외한 모든 내용을 해당 텍스트에서 제거하고 싶습니다 -. 따라서 이전 출력의 출력은 다음과 같아야 합니다.

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이는 쉘 자체의 내장 작업을 사용하는 것보다 훨씬 느립니다. 여기의 명령은 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

관련 정보