답변:
ls
전달 된 디렉토리의 파일과 내용을 인수로 나열하고, 인수가 없으면 현재 디렉토리를 나열합니다. 또한 동작에 영향을주는 여러 옵션을 전달할 수도 있습니다 ( man ls
자세한 내용 참조).
경우 ls
라는 인수를 전달되는 *
, 그것은라는 파일이나 디렉토리를 찾습니다 *
현재 디렉토리와는 다른 모든처럼 나열합니다. 캐릭터를 다른 방식으로 ls
취급하지 않습니다 *
.
그러나 경우 ls *
A는 쉘 커맨드 라인은 쉘이 확장되며, *
해당 셀에있어서의 로빙은 (이라고도 파일명 생성 또는 파일명 확장 규칙).
다른 쉘은 다른 globbing 연산자를 지원하지만 대부분은 가장 간단한 연산자에 동의합니다 *
. *
그래서 패턴으로, 문자의 수를 의미 *
A가 아니라 glob
그 패턴과 일치하는 현재 디렉토리에있는 파일 목록에 확장됩니다. 그러나 .
파일 이름 의 맨 앞에있는 점 ( ) 문자를 명시 적으로 일치 시켜야 한다는 점에서 예외 가 있으므로 *
실제로 .
사전 식으로 시작하지 않는 파일 및 디렉토리 목록으로 확장됩니다 .
현재 디렉토리라는 파일이 포함 된 경우 예를 들어, .
, ..
, .foo
, -l
과 foo bar
, *
에 전달할 두 개의 인수에 쉘에 의해 확장됩니다 ls
: -l
그리고 foo bar
당신이 입력 한 것처럼 될 것입니다, 그래서 :
ls -l "foo bar"
또는
'ls' "-l" foo\ bar
정확히 같은 명령을 실행하는 세 가지 방법이 있습니다. 세 가지 경우 모두, ls
명령 (에 /bin/ls
언급 된 디렉토리 조회에서 실행될 $PATH
것임)에는 "ls", "-l"및 "foo bar"라는 세 가지 인수가 전달됩니다.
또한이 경우 ls
첫 번째 (엄격하게 말하기 두 번째 ) 옵션을 옵션으로 취급합니다.
내가 말했듯이, 다른 쉘은 다른 globbing 연산자를 가지고 있습니다. 몇 년 전, zsh
도입 **/
짧게, 서브 디렉토리의 모든 수준에 맞게 의미 operator¹을 (*/)#
하고 ***/
디렉토리를 하강하면서 심볼릭 링크를 다음 것을 제외하고는 동일하다.
몇 년 전 (2003 년 7 월 ksh93o+
), ksh93
그 행동을 모방하기로 결정했지만 선택적으로하기로 결정했고 **
사건 만 다루었 다 (아닌 ***
). 또한 ksh93 **
에서 단독으로 특별하지는 않지만 zsh
( *
다른 전통적인 쉘에서 와 동일하게 의미가 있기 때문에 **
임의의 문자 수와 문자 수를 **
의미하므로) 현재와 같은 **/*
파일 또는 디렉토리 와 동일 (숨겨진 파일 제외).
bash
복사 ksh93
몇 년 후 (2009 월 배쉬 4.0) 동일한 구문하지만 불행한 차이 : bash는의가 **
같았다 zsh
의 ***
하위 디렉토리로 재귀 할 때 당신이 그것을 어떻게 원하는 것을 일반적으로하지 않은 심볼릭 링크를 따라했다, 즉되고 불쾌한 부작용이있을 수 있습니다. bash-4.3에서는 심볼릭 링크가 여전히 따랐다는 점에서 부분적으로 수정되었지만 재귀는 거기서 멈췄습니다. 5.0에서 완전히 수정되었습니다.
yash
**
이 extended-glob
옵션을 사용하면 2008 년 버전 2.0에 추가 되었습니다 . 그것의 구현은 혼자가 특별하지 않다는 zsh
점에서 더 가깝습니다 **
. 버전 2.15 (2009 년)에서는 추가 ***
같은에서 zsh
자체 확장이 : .**
와 .***
(에서 재귀 때 숨겨진 DIRS을 포함하는 zsh
의 D
글로브 규정 에서와 같이이 ( **/*(D)
하지만) 숨김 파일 및 디렉토리를 고려할 것입니다 만 숨겨진 통과하려면 숨겨진 파일은 확장 할 수 없지만 ((*|.*)/)#*
또는 **/[^.]*(D)
) 가 필요합니다 .
물고기 쉘 도 지원합니다 **
. 의 이전 버전과 마찬가지로 bash
디렉토리 트리를 내릴 때 심볼릭 링크를 따릅니다. 그러나 그 쉘에서는와는 **/*
다릅니다 **
. **
더 확장되어 *
여러 디렉토리에 걸쳐있을 수 있습니다. 에서 fish
, **/*.c
일치 a/b/c.c
하지만 a.c
반면, a**.c
일치 a.c
와 ab/c/d.c
와 zsh
의 **/.*
예를 들어 서면되어야한다 .* **/.*
. 그곳 ***
으로 이해 **
이어 *
지도록 동일 **
.
tcsh
또한 globstar
V6.17.01 (2010 년 5 월)에 옵션이 추가 **
되었으며 ***
à la를 모두 지원합니다 zsh
.
그래서에서 tcsh
, bash
그리고 ksh93
(해당 옵션이 활성화 된 경우 ( globstar
)) 또는 fish
, **
현재의 아래의 모든 파일과 디렉토리를 확장하고, ***
과 동일 **
위한 fish
횡단 심볼릭 링크, **
위해 tcsh
와 globstar
,와 같은 *
에서 bash
와 ksh93
그것의 비록 ( 미래 버전의 해당 쉘이 심볼릭 링크를 통과한다는 것은 불가능하지 않습니다).
위에서는 확장이 옵션으로 해석되지 않았는지 확인해야합니다. 이를 위해 다음을 수행하십시오.
ls -- *
또는:
ls ./*
일부 파일 이름을 사용 ls
하더라도 --
특수하게 처리 될 수 있기 때문에 두 번째 명령이 선호되는 명령은 중요하지 않습니다 . 이 경우의 -
대부분의 텍스트 유틸리티, cd
및 pushd
포함 된 파일 이름과 =
에 대한 문자를 awk
예를 들어 있습니다. ./
모든 인수 앞에 추가 하면 특별한 의미가 제거됩니다 (적어도 위에서 언급 한 경우).
또한 대부분의 쉘은 또한 참조 (일치 존재하지 않는 경우는 어떻게 해야할지, 정렬 순서를 점 파일을 무시할지 여부를 싫든, ...)이 글 로빙 동작에 영향을주는 옵션을 가지고 있음을 주목해야한다 $FIGNORE
매개 변수ksh
또한, 모든 쉘에 있지만 csh
, tcsh
, fish
및 zsh
경우, 글 로빙 패턴이 어떤 파일과 일치하지 않습니다, 패턴이 혼란 가능성이 버그를 일으키는 확장되지 않은 인수로 전달됩니다. 예를 들어 현재 디렉토리에 숨겨지지 않은 파일이없는 경우
ls *
실제로 호출 ls
두 개의 인수 ls
와 *
. 거기에 어떤 파일이 전혀 없다, 그래서 아무도 호출되지로서 그리고 *
하나, 당신은에서 오류 메시지가 나타납니다 LS : 같은 (셸이 아닌) ls: cannot access *: No such file or directory
사람들이 그것이라고 생각하는 것으로 알려져있다, ls
즉 실제로 globs의 확대되었다.
다음과 같은 경우 문제가 더욱 악화됩니다.
rm -- *.[ab]
더 있다면 *.a
나 *.b
현재 디렉토리에 파일을, 당신은라는 파일 삭제 끝낼 없습니다 수도 *.[ab]
실수를 ( csh
, tcsh
, 및 zsh
보고서 것 없이 일치 오류 및 호출 할 것이다 rm
(그리고 fish
지원하지 않는 [...]
와일드 카드)).
당신은 문자 그대로 전달하려는 경우 *
에를 ls
, 당신은 그 인용이 *
같이 어떤 식 으로든 문자 ls \*
또는 ls '*'
나 ls "*"
. POSIX와 같은 쉘에서 사용하여 완전히 비활성화 할 수 있습니다 대체 (globbing) set -o noglob
또는 set -f
(후자에서 작동하지 않는 zsh
에서하지 않는 한 sh
/ ksh
에뮬레이션).
¹ (*/)#
항상 지원 되었지만 처음 ..../
에는 zsh-2.0에서 와 같이 (그리고 잠재적으로 이전에), ****/
2.1 **/
에서 1992 년 초에 확정 된 형태 를 갖기 전에 2.1로 사용 되었습니다.
find -name *
입니다. 특히 더 복잡한 패턴을 사용하여 현재 디렉토리에 정확히 하나의 일치 항목이 있으면 사람들은 별표를로 전달하지 않는다는 사실을 종종 알지 못합니다 find
.
*.[ab]
끝나는 모든 것을 삭제하려고 시도합니다 .[ab]
. [
물고기는 특별하지 않습니다.
이 명령의 ls
기본값은 ls .
다음과 같습니다 . 현재 디렉토리의 모든 항목을 나열합니다 .
이 명령 ls *
은 ' *
쉘 패턴 확장시 ls를 실행합니다'를 의미합니다
*
패턴은 쉘에 의해 처리하고, 그 시작을 제외하고, 현재의 디렉토리의 모든 항목 확장된다 .
. 한 단계 깊숙이 갈 것입니다.
이중 또는 삼중 *
패턴 의 해석은 사용 된 실제 쉘에 따라 다릅니다.
*
0 개 이상의 문자와 일치하는 와일드 카드입니다. 일부 현대 쉘은 **
패턴 을 볼 때 하위 디렉토리로 재귀합니다 .
*
할 뭔가를 추가 globstar을 설명하는 다른 대답을 참조하십시오. 또한 LS가없는 것이 분명해야한다 아무것도 별표와 함께 할을 전혀 이러한 별표 중 하나를 통과 적이 없어요. echo ls *
당신이 쓸 때 무엇이 실행될 것인지보기 위해 달려라 ls *
.
명령이 무엇으로 확장되는지 확인하기 위해 먼저 입력하는 echo
대신 전체 프로세스를 ls
이해할 수 있습니다.
$ echo *
Applications Downloads Documents tmp.html
그래서이 경우 ls *
에 확장ls Applications Downloads Documents tmp.html
$ echo **
Applications Downloads Documents tmp.html
$ echo ***
Applications Downloads Documents tmp.html
따라서 변화가 없습니다. 이것은 bash
쉘로 사용한다고 가정합니다. 대부분의 사람들이 있고 다른 쉘은 다른 동작을합니다. ash
또는 csh
또는 ksh
또는 또는를 사용하는 경우 zsh
상황이 다르게 작동 할 수 있습니다. 그것은 다른 껍질을 가지고있는 요점입니다.
따라서 다른 작업을 계속 시도해 bash
보아 글 로빙 ( *
) 연산자가 우리를 위해 할 수있는 아이디어를 얻 습니다. 예를 들어 이름의 일부를 기준으로 필터링 할 수 있습니다.
$ echo D*
Downloads Documents
흥미롭게도, 후행 슬래시는 내재적으로 모든 디렉토리 이름의 일부입니다. 따라서 */
디렉토리와 디렉토리에 대한 심볼릭 링크 만 생성됩니다.
$ echo */
Applications/ Downloads/ Documents/
그리고 중간에 슬래시를 넣어 여러 수준에서 필터링을 수행 할 수 있습니다.
$ echo D*/*/
Documents/Work/ /Documents/unfinished/
때문에 Downloads
디렉토리 하위 디렉토리를 포함하지 않는, 그것은 출력에서 끝나지 않습니다. 이것은 원하는 파일을 검사하는 데 매우 유용합니다. 나는 항상 이와 같은 명령을 사용합니다 :
$ ls -l /home/*/public_html/wp-config.php
여기에는 wp-config.php
사용자 public_html
디렉토리 의 기본 레벨에 존재하는 모든 파일 이 나열됩니다 . 또는 더 완벽 할 수도 있습니다.
$ find /home/*/public_html/ -name wp-config.php
이것은 어떤 찾을 수 wp-config.php
있는 사용자의 파일 public_html
디렉토리 또는 하위 디렉토리 중 하나를하지만,보다 효율적보다는 다만 작동 find /home/ -name wp-config.php
이 아무것도 조사하지 않기 때문에 하지만public_html
각 사용자에 대한 디렉토리를.
bash
당신의 쉘로 사용 하고 있다고 가정합니다 "← 그리고 globstar가 활성화되어 있지 않습니다. shopt -s globstar
다시 시도해보십시오.
set -x
은 "매번 실행되는"실제 "명령 인쇄를 시작하는 것 set +x
입니다.
globstar
옵션이 활성화 된 bash 4.x를 포함한 일부 셸에서는 **
일치하는 디렉토리를 내림차순으로 재귀 글로브를 수행합니다. 추가 별표는이 작업을 더 이상 수정하지 않습니다.
ksh93
하고 zsh
, bash
일반적으로 원치 않는 것입니다 재귀에 트래버스 심볼릭 링크를한다.
"심층 다이빙"을하려면 ls -R (재귀) 옵션을 사용하거나 다음과 같이 find를 사용하십시오.
find . -ls
"find"는 디렉토리 트리의 맨 아래로 내려 가며 ( 'ls -R'처럼) 디렉토리 나열 (-type d), 파일 만 (-type f) 또는 다른 파일이있는 파일 표시와 같은 더 많은 옵션이 있습니다. 특성 (/ etc / passwd의 사용자, 특정 권한 및 그 이상) "find"는 스크립팅에서 다소 안전합니다 (쉘 사이에 일관성없는 글 로빙 규칙 및 대시가있는 파일의 특수 이스케이프 등).
쉘 와일드 카드 글 로빙은 점 파일에서 별표 '*'와 함께 작동하지 않습니다. 도트 파일 만 나열하려면 다음을 사용하십시오.
ls .??*
추가 * 깊이 수준을 추가하지 않습니다. 하지만 시도하면
ls */*/*
-현재 폴더의 폴더에 하위 폴더의 하위 폴더 목록이 표시됩니다.
*
의 깊이가 추가됩니다.
bash
globstar 옵션, korn 쉘 및 zsh와 함께 GNU 를 포함 합니다. 그리고 아마도 다른 것 같아요. unix.stackexchange.com/a/62665/14831