답변:
a*
및 *a*
구문은하지에 의해, 쉘에 의해 구현되는 ls
명령.
입력 할 때
ls a*
쉘 프롬프트에서 쉘 a*
은 이름이로 시작하는 현재 디렉토리의 모든 기존 파일 목록으로 확장 됩니다 a
. 예를 들어, a*
시퀀스로 확장 하고 a1 a2 a3
인수로 인수로 전달할 수 ls
있습니다. ls
명령 자체 결코는보고 *
문자를; 단지 세 개의 인수 a1
인 a2
, 및을 볼 수 a3
있습니다.
와일드 카드 확장을 위해 "파일"은 현재 디렉토리의 모든 엔티티를 나타냅니다. 예를 들어, a1
일반 파일 일 a2
수도 있고 디렉토리 일 a3
수도 있고 심볼릭 링크 일 수도 있습니다. 그것들은 모두 디렉토리 엔트리를 가지고 있으며, 쉘의 와일드 카드 확장은 해당 엔트리가 어떤 종류의 엔티티를 참조하는지 상관하지 않습니다.
실제로 모든 쉘 (bash, sh, ksh, zsh, csh, tcsh 등)은 와일드 카드를 구현합니다. 세부 사항은 다를 수 있지만 *
0 개 이상의 문자를 ?
일치 시키고 단일 문자 를 일치 시키는 기본 구문 은 상당히 일관성이 있습니다.
특히 bash의 경우 bash 매뉴얼의 "파일 이름 확장"섹션에 설명되어 있습니다. info bash
"파일 이름 확장"을 실행 하고 검색하거나 여기를 참조 하십시오 .
이것은 개별 명령이 아니라 쉘에 의해 수행된다는 사실은 몇 가지 흥미로운 (때로는 놀라운) 결과를 가져옵니다. 이에 대한 가장 좋은 점은 와일드 카드 처리가 모든 명령에 대해 (거의) 일관성이 있다는 것입니다 . 만약 쉘이 이것을하지 않았다면 필연적으로 어떤 명령들은 귀찮게하지 않을 것이고, 다른 것들은 저자가 "더 나은"것으로 생각한 미묘하게 다른 방식으로 그것을 할 것입니다. (Windows 명령 셸 에이 문제가 있다고 생각하지만 더 이상 언급 할 수는 없습니다.)
반면에 여러 파일의 이름을 바꾸는 명령을 작성하는 것은 어렵습니다. 당신이 쓰는 경우 :
mv *.log *.log.bak
*.log.bak
현재 디렉토리에 이미 존재하는 파일을 기반으로 확장 되었기 때문에 실패했을 것입니다 . 이런 종류의 작업을 수행하는 명령이 있지만 파일의 이름을 바꾸는 방법을 지정하려면 고유 구문을 사용해야합니다. 와 같은 일부 명령 find
은 자체 와일드 카드 확장을 수행 할 수 있습니다. 쉘의 확장을 억제하기 위해 인수를 인용해야합니다.
find . -name '*.txt' -print
쉘의 와일드 카드 확장은 전적으로 명령 행 인수의 구문과 기존 파일 세트를 기반으로합니다. 그것은 할 수없는 명령의 의미에 의해 영향을받을. 예를 들어, 모든 .log
파일을 상위 디렉토리 로 이동 하려면 다음을 입력하십시오.
mv *.log ..
당신이 잊어 버린 경우 ..
:
mv *.log
.log
현재 디렉토리에 정확히 두 개의 파일이 있으면 다음과 같이 확장됩니다.
mv one.log two.log
이름이 one.log
바뀌고 클로버가 two.log
됩니다.
편집 : 그리고 52 upvotes, 수락 및 전문가 배지 후, 실제로 제목의 질문에 대답해야합니다.
-d
또는 --directory
옵션은하는 ls
디렉토리 만 나열하도록 지시하지 않습니다. 디렉토리는 내용이 아닌 그대로 디렉토리를 나열하도록 지시합니다. 디렉토리 이름을에 인수로 지정 ls
하면 기본적으로 디렉토리 의 내용 이 나열 됩니다. 일반적으로 관심있는 항목 -d
이므로 디렉토리 자체 만 나열하도록합니다. 와일드 카드와 결합 할 때 특히 유용합니다. 입력하면 :
ls -l a*
ls
이름이로 시작하는 각 파일 과 이름이로 시작되는 각 디렉토리 a
의 내용 을 길게 나열 합니다 a
. 파일과 디렉토리 목록을 원하는 경우 각각 한 줄씩 사용할 수 있습니다.
ls -ld a*
이는 다음과 같습니다.
ls -l -d a*
ls
명령이 *
문자를 보지 못한다는 것을 다시 기억하십시오 .
이것이 문서화 된 곳은 거의 모든 유닉스 계열 시스템 man ls
에서 ls
명령에 대한 문서를 보여줍니다 . 대부분의 Linux 기반 시스템 ls
에서이 명령은 GNU coreutils 패키지의 일부입니다. 당신이있는 경우에 info
명령을 하나 info ls
또는 info coreutils ls
더 많은 최종적이고 포괄적 인 문서를 제공해야합니다. MacOS와 같은 다른 시스템은 다른 버전의 ls
명령을 사용할 수 있으며 명령이 없을 수 있습니다 info
. 해당 시스템의 경우을 사용하십시오 man ls
. 그리고 ls --help
쇼됩니다 상대적으로 짧은 사용법 메시지 (내 시스템에 117 선) 된 경우 는 GNU의로 coreutils 구현을 사용하고 있습니다.
그렇습니다. 전문가조차도 문서를 참고해야합니다. 이 고전적인 농담을 참조하십시오 .
a*
의 모든 파일 목록으로 확장됩니다 . a
ls subdir/a*
echo
입니다. 당신이 할 때 무슨 일이 일어나고 있는지 알고 싶다면 ls a*
, 먼저 실행echo ls a*
echo a*
... 쉘은 어쨌든 확장을 수행합니다
shopt -s failglob
에서 동일한 동작이 발생합니다. 예를 들어, 설정 nullglob
하지 않지만 빈 문자열로 확장됩니다. failglob
*nosuchfile*
Keith Thompson의 답변을 참조하십시오. 그러나 ls --directory a*
파일 과 디렉토리를 표시 하는 이유를 설명하려면 :이 --directory
옵션은 디렉토리가 아닌 파일을 억제하지 않습니다. 대신 디렉토리를 그대로 나열하고 내용을 나열합니다. 예:
$ mkdir foo
$ touch foo/bar
$ ls foo
bar
$ ls --directory foo
foo
-F
옵션에 더욱 매력적입니다.
매우 명확하게하기 위해, ls (1) 매뉴얼 페이지에 문서화되어 있습니다 :
-d, --directory 는 내용 대신 디렉토리 항목을 나열하고 기호 링크를 역 참조하지 않습니다.
공정하게 말하면, "컨텐츠 대신 엔트리"는 아마도 더 설명적일 수 있습니다 :
FILE이 디렉토리 인 경우 해당 디렉토리의 내용을 나열하는 대신 디렉토리 항목 자체를 표시하십시오. FILE이 기호 링크 인 경우 링크가 가리키는 파일 대신 링크 항목 자체를 표시하십시오.
설명했듯이 Unix 전문 용어에서는 *
확장 (및 유사한 확장)을 glob
빙 (bing )이라고하며 일반적으로 명령 프로세서의 기능입니다 (Unix 용어에서는 "쉘"이라고 함). 따라서 다른 많은 곳에서도 globbing을 사용할 수 있습니다. 입력 man 7 glob
고전적인 리눅스 배포판의 쉘에서 (또는 볼 이 )에 대한 자세한을 위해 glob
빙.
초기 유닉스에서 glob
실제로 구현 된 별도의 프로그램 이라고합니다 /etc/glob
(10 페이지 참조 이 오래된 UNIX 설명서를 그에 대한 문서에 대한). 요즘은 코드 라이브러리에서 제공하는 코드 루틴이며 일반적으로 쉘에서 사용됩니다. 출처 : Wikipedia .
ls -d
디렉토리뿐만 아니라 파일을 나열 하는 이유에 관해서 는 ...
ls
매뉴얼 페이지 이런 일이 발생하는 이유하지만 아주 간결한 설명과 함께 설명합니다. 다음은 확장 된 설명에 대한 시도입니다.
기본적 으로 디렉토리 이름이 주어지면 디렉토리 ls
의 내용 이 나열 되며 디렉토리에 대한 심볼릭 링크 에 대해 동일한 작업을 수행합니다 . 이 -d
옵션은 "디렉토리 이름 (들)이 주어진 경우"( bing에 의해 암시 적 으로 주어질 수도 있음 glob
)을 의미하며, 디렉토리의 _name_s 만 표시하고 내용은 표시 하지 않습니다 . 마찬가지로, 디렉토리에 대한 심볼릭 링크의 이름 (명시 적 또는 암시 적 )을 제공 하는 경우 참조하는 디렉토리의 내용이 아닌 심볼릭 링크의 파일 이름을 표시하십시오.
-d
옵션은 아무 상관이없는, 지금까지의 내가 함께 말할 수 있는 항목이 나열되어 있습니다; (출처 :이 수행 할 수 있습니다 여기 와) find
과 같이, : find . -maxdepth 1 -type d
. GNU로만 그렇게하는 좋은 방법이 있는지 확실하지 않습니다 ls
. 다음 은 find
명령 사용법에 대한 몇 가지 예입니다 .
요약하자면, 기본적으로 ls
경로 이름이 주어지면 디렉토리의 내용이 표시됩니다. -d
표준 파일에서와 같이 디렉토리 이름 자체 만 표시하여이 동작을 변경합니다.
문서 는 디렉토리 이름 만 수신 할 때 디렉토리 항목 만 나열한다고 말하지 않으며 내용 대신ls
디렉토리 항목을 나열 합니다. 이해하는 가장 좋은 방법은 다음과 같습니다.
> {ice} ~ :10:47 % ls -l /
total 97
drwxr-xr-x 2 root root 4096 May 3 00:27 bin
drwxr-xr-x 4 root root 1024 May 3 14:17 boot
drwxr-xr-x 2 root root 4096 Apr 29 13:44 cdrom
drwxr-xr-x 18 root root 4420 May 9 09:58 dev
...
lrwxrwxrwx 1 root root 33 May 3 14:16 vmlinuz -> boot/vmlinuz-3.9.0-030900-generic
lrwxrwxrwx 1 root root 29 May 3 11:07 vmlinuz.old -> boot/vmlinuz-3.8.0-19-generic
> {ice} ~ :10:47 % ls -ld /
drwxr-xr-x 25 root root 4096 May 3 14:16 /
문서는 쉘의 일부입니다 . 특히 셸은 명령을 실행하기 전에 특정 순서로 다양한 확장 및 대체 를 수행합니다.
Bourne 호환 쉘 의 단어 확장 순서 는 다음과 같습니다.
따라서 ls
명령은 *
문자를 볼 수 없으며 인수는 a*
glob 패턴 과 일치하는 모든 파일로 이미 확장되었습니다 . 파일 이름 globbing이 필요한 각 명령이이 기능 자체를 구현해야하는 Windows와는 다릅니다.
필요한 키워드 ( man bash
)는 "Pathname Expansion"입니다.