다음과 같은 파일 목록이 있습니다.
$ echo *
add akfefg aka ab ba
"a"와 "b"가 순서대로 포함된 파일 이름을 에코하고 싶습니다. 나는 노력했다
echo *[ab]*[ba]*
aka ab ba
"aka"도 인쇄합니다. 나는 노력했다
$ echo *a*b* && echo *b*a*
ab
ba
제 역할을 하지만 다음 줄에 'ba'가 인쇄됩니다. 이 작업을 수행하는 더 쉬운 방법이 있나요? 감사해요.
답변1
이 답변에서는 두 가지 시나리오를 해결하고 있습니다.
a
현재 디렉터리에서 및 를 모두 포함하는 파일 이름을 일치시키려고 합니다 .b
그런 다음 이 파일로 뭔가를 하고 싶습니다.- 줄 바꿈을 제거하기 위해 두 명령의 출력을 처리하려고 합니다
echo
.
파일 이름을 반복하려면 모든 이름과 일치하는 패턴을 만든 다음 루프에서 해당 패턴의 확장을 사용하는 것이 좋습니다. echo
이는 개별 파일 이름 간의 구별을 제거하므로 권장되지 않습니다.
zsh
셸 에서는 단일 패턴이 임의의 순서로 나타나는 문자 와 모든 이름 (*a*b*|*b*a*)
으로 확장됩니다 .a
b
bash
셸 에서는 단일 확장된 globbing 패턴(또는 ksh
유사한 globbing 패턴) 을 사용하여 @(*a*b*|*b*a*)
동일한 작업을 수행할 수 있습니다. 기본적으로 셸은 bash
확장 글로빙 모드를 활성화하지 않으므로 먼저 해당 모드를 활성화해야 합니다 shopt -s extglob
.
따라서 bash
쉘에서는 다음과 같은 것을 사용할 수 있습니다.
shopt -s extglob
for name in @(*a*b*|*b*a*); do
# process "$name" here
done
필요한 파일 이름을 생성하는 또 다른 방법처리를 위해다음을 사용하는 것입니다 find
.
find . ! -name . -prune -name '*a*' -name '*b*'
a
그러면 현재 디렉토리에서 및 가 모두 포함된 이름 만 찾습니다 b
. 그런 다음 -exec
이 명령의 끝 부분에서 를 사용하여 작업을 수행하는 다른 유틸리티를 호출할 수 있습니다 .
find . ! -name . -prune -name '*a*' -name '*b*' -exec sh -c '
for name do
# process "$name" here
done' sh {} +
여기서는 find
인라인 스크립트를 생성하는 sh -c
데 사용되는 파일 이름입니다 . 당신은 또한 볼 수 있습니다"find"의 -exec 옵션 이해
하지만,이것이 텍스트 처리 연습인 경우목적은 두 개 이상의 텍스트 줄( echo
두 호출의 출력)을 한 줄로 정렬하는 것입니다. 그런 다음 텍스트를 파이핑하여 수행할 수 있습니다 paste -s -
. 그러면 파일 이름에 포함된 개행 문자도 제거됩니다. paste
대신 이 방법(개행 문자도 제거)을 사용하면 tr -d '\n'
결과 텍스트가 끝에 단일 개행 문자로 종료됩니다.
답변2
대괄호를 사용할 필요가 없으며 다양한 문자와 일치합니다. 두 번째 예에서는 &&
여러 명령을 순서대로 실행하는 데 사용되는 연산자를 사용했습니다 . 이것이 파일이 한 줄씩 인쇄되는 이유입니다.
빨리 달려$ echo *a*b* *b*a*
그러면 모든 파일이 한 줄에 인쇄됩니다.
예를 들어 중복된 일치 항목을 편집합니다 cacbca
.
확장된 와일드카드를 사용할 수 있습니다. 먼저 bash에서 활성화하세요.$ shopt -s extglob
그런 다음 스키마를 다음과 같이 재정의합니다.
$ printf '%s ' @(*a*b*|*b*a*)
@(pattern-list)는 주어진 패턴 중 하나와 일치합니다.