패턴 검색 및 디렉토리의 파일 나열을 위한 쉘 스크립트

패턴 검색 및 디렉토리의 파일 나열을 위한 쉘 스크립트

ls | agrep "<search pattern #1>;<search pattern #2>;...;<search pattern #n>"나는 디렉토리에 있는 특정 파일의 검색/목록을 신속하고 효율적으로 수행하기 위해 특정 검색 패턴을 사용했습니다 . 예를 들어, 빈 디렉토리를 만들고 touch다음을 사용하여 빈 파일로 채웠습니다.

~ ls -l
total 0
-rw-r--r-- 1 me users 0 May  7 14:00 animals-bird_dog_cat.txt
-rw-r--r-- 1 me users 0 May  7 14:00 animals-bird_dog.txt
-rw-r--r-- 1 me users 0 May  7 14:00 animals-bird.txt
-rw-r--r-- 1 me users 0 May  7 14:00 animals-cat_dog_bird.txt
-rw-r--r-- 1 me users 0 May  7 14:00 animals-cat_dog.txt
-rw-r--r-- 1 me users 0 May  7 14:00 animals-cat.txt
-rw-r--r-- 1 me users 0 May  7 14:00 animals-dog_bird.txt
-rw-r--r-- 1 me users 0 May  7 14:00 animals-dog_cat_bird.txt
-rw-r--r-- 1 me users 0 May  7 14:00 animals-dog_cat.txt
-rw-r--r-- 1 me users 0 May  7 14:00 animals-dog.txt

그런 다음 을 사용하여 ls -l | agrep "cat;bird"이름에 다음만 포함된 파일을 검색/찾을 수 있습니다.고양이그리고다음과 같습니다.

~ ls -l | agrep 'cat;bird'
-rw-r--r-- 1 me users 0 May  7 14:00 animals-bird_dog_cat.txt
-rw-r--r-- 1 me users 0 May  7 14:00 animals-cat_dog_bird.txt
-rw-r--r-- 1 me users 0 May  7 14:00 animals-dog_cat_bird.txt

AFAICT, 이 방법은 매우 빠르고 효과적입니다(저는 더 나은 솔루션을 원합니다). 이 작업을 매일 많이 하기 때문에 CLI에서 검색 패턴을 제공하여 이러한 작업을 수행할 수 있는 간단한 쉘 스크립트를 작성하는 것이 가장 좋겠다고 생각했습니다. 예를 들어 아래와 같이 간단한 쉘 스크립트를 작성하고 이름을 지정 mls하고 실행 가능하게 만들었습니다.

#!/bin/bash
bold=$(tput bold)
italic=$(tput sitm)
normal=$(tput sgr0)
if [ "$#" -lt 1 ]; then
    echo "${bold}Usage${normal}: $0 <search string 0> [... <search string n>]"
    exit 0
fi
patterns=""
for ((i=1;i<$#;i++))
do
    patterns+="${!i};"
done
patterns+="${!#}"
/usr/bin/ls -lart | agrep '${patterns}${!#}'

그런 다음 검색 모드를 사용하여 위의 셸 스크립트를 실행하면 mls cat bird아래와 같이 아무것도 반환되지 않습니다.

~ ls -l | agrep 'cat;bird'
-rw-r--r-- 1 me users 0 May  7 14:00 animals-bird_dog_cat.txt
-rw-r--r-- 1 me users 0 May  7 14:00 animals-cat_dog_bird.txt
-rw-r--r-- 1 me users 0 May  7 14:00 animals-dog_cat_bird.txt
~ mls cat bird
~

내가 놓친 게 무엇입니까?

답변1

여기서 전환할 수 있습니다 zsh. 해당 glob은 OR, AND(및 AND-NOT 및 NOT) 및 근사를 지원합니다.

$  set -o extendedglob # best in ~/.zshrc
$ ls -ld -- (#a1)*dig*~^(#a1)*bard*
-rw-rw-r-- 1 chazelas chazelas 0 May  8 16:24 animals-bird_dog_cat.txt
-rw-rw-r-- 1 chazelas chazelas 0 May  8 16:24 animals-bird_dog.txt
-rw-rw-r-- 1 chazelas chazelas 0 May  8 16:24 animals-cat_dog_bird.txt
-rw-rw-r-- 1 chazelas chazelas 0 May  8 16:24 animals-dog_bird.txt
-rw-rw-r-- 1 chazelas chazelas 0 May  8 16:24 animals-dog_cat_bird.txt

답변2

작은 따옴표 문제 외에도 마지막 요소를 두 번 추가합니다.

patterns+="${!#}"
/usr/bin/ls -lart | agrep "${patterns}${!#}"

프로그램을 실행하면 bash -x mls cat bird볼 수 있어요


그러나 루프는 필요하지 않습니다. "$*"특수 매개변수는 IFS의 첫 번째 문자를 사용하여 위치 매개변수를 연결합니다. IFS에 대한 새로운 값을 일시적으로 정의하면 다음을 수행할 수 있습니다.

patterns=$( IFS=';'; echo "$*" )

"근사" 부분이 필요하지 않은 경우 agrepbash는 다음을 사용하여 직접 수행할 수 있습니다.확장된 전역 모드.

pattern=$( IFS='|'; echo "$*" )
shopt -s extglob
ls *@($pattern)*

관련 정보