development

bash에서 ls를 사용하여 디렉토리 만 나열 : 검사

big-blog 2020. 9. 28. 09:33
반응형

bash에서 ls를 사용하여 디렉토리 만 나열 : 검사


이 명령은 현재 경로의 디렉토리를 나열합니다. ls -d */

패턴 */정확히 무엇을 합니까?

그리고 위의 명령 (예 ls -d /home/alice/Documents:)에서 해당 경로의 디렉토리 만 나열하기 위해 어떻게 절대 경로를 제공 할 수 있습니까?


*/는 현재 디렉토리의 모든 하위 디렉토리와 일치하는 패턴입니다 ( *모든 파일 하위 디렉토리 일치 하고 디렉토리로 /제한됨). 마찬가지로 / home / alice / Documents 아래의 모든 하위 디렉토리를 나열하려면ls -d /home/alice/Documents/*/


이를 수행하는 네 가지 방법, 각각 다른 출력 형식

1. 사용 echo

예 : echo */, echo */*/
내가 얻은 정보는 다음과 같습니다.

cs/ draft/ files/ hacks/ masters/ static/  
cs/code/ files/images/ static/images/ static/stylesheets/  

2. 사용 ls

예 : ls -d */
정확히 내가 얻은 것입니다.

cs/     files/      masters/  
draft/  hacks/      static/  

또는 목록 (상세 정보 포함) : ls -dl */

3. 사용 lsgrep

예 : ls -l | grep "^d"내가 얻은 것은 다음과 같습니다.

drwxr-xr-x  24 h  staff     816 Jun  8 10:55 cs  
drwxr-xr-x   6 h  staff     204 Jun  8 10:55 draft  
drwxr-xr-x   9 h  staff     306 Jun  8 10:55 files  
drwxr-xr-x   2 h  staff      68 Jun  9 13:19 hacks  
drwxr-xr-x   6 h  staff     204 Jun  8 10:55 masters  
drwxr-xr-x   4 h  staff     136 Jun  8 10:55 static  

4. Bash 스크립트 (공백이 포함 된 파일 이름에는 권장되지 않음)

예 : for i in $(ls -d */); do echo ${i%%/}; done
내가 얻은 것은 다음과 같습니다.

cs  
draft  
files  
hacks  
masters  
static

끝 문자로 '/'를 사용하려는 경우 명령은 다음과 같습니다. for i in $(ls -d */); do echo ${i}; done

cs/  
draft/  
files/  
hacks/  
masters/  
static/

나는 사용한다:

ls -d */ | cut -f1 -d'/'

이렇게하면 후행 슬래시가없는 단일 열이 만들어져 스크립트에 유용합니다.

내 2 센트.


하위 폴더가 없는 모든 폴더 :

find /home/alice/Documents -maxdepth 1 -type d

하위 폴더가 있는 모든 폴더 :

find /home/alice/Documents -type d

4 (more) 신뢰할 수있는 옵션.

인용 부호로 둘러싸이지 않은 별표 *쉘 패턴 (글로브)로 해석됩니다.
쉘은 경로명 확장에이를 사용합니다.
그런 다음 패턴과 일치하는 파일 이름 목록을 생성합니다.
간단한 별표는 PWD (현재 작업 디렉토리)의 모든 파일 이름과 일치합니다.
*/끝나는 모든 파일 이름과 일치 하는 더 복잡한 패턴 입니다 /.
따라서 모든 디렉토리. 이것이 바로 다음 명령의 이유입니다.

1.- 에코.

echo */
echo ./*/              ### avoid misinterpreting filenames like "-e dir"

echo에 의해 PWD의 모든 디렉토리 로 확장됩니다 .


이를 테스트하려면 다음 mkdir과 같이하십시오. test-dir과 같은 이름 의 디렉토리 ( )를 생성 cd합니다.

mkdir test-dir; cd test-dir

일부 디렉토리를 만듭니다.

mkdir {cs,files,masters,draft,static}   # safe directories.
mkdir {*,-,--,-v\ var,-h,-n,dir\ with\ spaces}  # some a bit less secure.
touch -- 'file with spaces' '-a' '-l' 'filename'    # and some files:

이 명령 echo ./*/은 이름이 이상한 파일에서도 안정적으로 유지됩니다.

./--/ ./-/ ./*/ ./cs/ ./dir with spaces/ ./draft/ ./files/ ./-h/
./masters/ ./-n/ ./static/ ./-v var/

그러나 파일 이름의 공백은 읽기를 약간 혼란스럽게 만듭니다.


대신를 echo사용 ls하면 셸은 여전히 ​​파일 이름 목록을 확장하는 것입니다. 쉘은 PWD에서 디렉토리 목록을 얻는 이유입니다. -d에 옵션 ls차종은 대신 (기본적으로 제시된) 각 디렉토리의 내용을 본 디렉토리 항목을 나열합니다.

ls -d */

그러나이 명령은 (다소) 덜 신뢰할 수 있습니다. 위에 나열된 이상한 이름의 파일로 인해 실패합니다. 여러 이름으로 질식합니다. 문제가있는 것을 찾을 때까지 하나씩 지워야합니다.

2.- ls

GNU ls는 "옵션 끝"( --) 키 를 받아들 입니다.

ls -d ./*/                     ### more reliable BSD ls
ls -d -- */                    ### more reliable GNU ls

3.-printf

각 디렉토리를 자체 행에 나열하려면 (ls -1과 유사하게 한 열에) 다음을 사용하십시오.

$ printf "%s\n" */        ### Correct even with "-", spaces or newlines.

그리고 더 좋은 점은 후행을 제거 할 수 있다는 것입니다 /.

$ set -- */; printf "%s\n" "${@%/}"        ### Correct with spaces and newlines.

다음과 같은 시도 :

$ for i in $(ls -d */); do echo ${i%%/}; done

다음에서 실패합니다.

  • ls -d */위에 이미 표시된 일부 이름 ( ).
  • 값의 영향을받습니다 IFS.
  • 공백과 탭에서 이름을 분할합니다 (기본값 IFS).
  • 이름의 각 줄 바꿈은 새로운 echo 명령을 시작합니다.

4.- 기능

마지막으로 함수 내에서 인수 목록을 사용하면 현재 실행중인 셸의 인수 목록에 영향을주지 않습니다. 간단히:

$ listdirs(){ set -- */; printf "%s\n" "${@%/}"; }
$ listdirs

이 목록을 제공합니다.

--
-
*
cs
dir with spaces
draft
files
-h
masters
-n
static
-v var

이 옵션은 여러 유형의 이상한 파일 이름으로 안전합니다.


tree명령은 여기에서도 매우 유용합니다. 기본적으로 모든 파일과 디렉토리를 완전한 깊이로 표시하며 일부 ASCII 문자는 디렉토리 트리를 표시합니다.

$ tree
.
├── config.dat
├── data
│   ├── data1.bin
│   ├── data2.inf
│   └── sql
|   │   └── data3.sql
├── images
│   ├── background.jpg
│   ├── icon.gif
│   └── logo.jpg
├── program.exe
└── readme.txt

그러나 ascii 트리없이 현재 디렉토리의 전체 경로를 사용하여 디렉토리 만 가져 오려면 다음을 수행 할 수 있습니다.

$ tree -dfi
.
./data
./data/sql
./images

인수는 다음과 같습니다.

-d     List directories only.
-f     Prints the full path prefix for each file.
-i     Makes tree not print the indentation lines, useful when used in conjunction with the -f option.

그런 다음 절대 경로를 원하면 현재 디렉토리의 전체 경로를 지정하여 시작할 수 있습니다.

$ tree -dfi "$(pwd)"
/home/alice/Documents
/home/alice/Documents/data
/home/alice/Documents/data/sql
/home/alice/Documents/images

그리고 하위 디렉터리의 수를 제한하려면 다음과 같이를 사용하여 하위 디렉터리의 최대 수준을 설정할 수 있습니다 -L level.

$ tree -dfi -L 1 "$(pwd)"
/home/alice/Documents
/home/alice/Documents/data
/home/alice/Documents/images

맨 트리에서 더 많은 논쟁을 볼 수 있습니다.


'ls -d * /'의 출력이 왜 다음과 같이 두 개의 후행 슬래시를 제공하는지 궁금한 경우 :

[prompt]$ ls -d */    
app//  cgi-bin//  lib//        pub//

아마도 쉘 또는 세션 구성 파일 어딘가에서 ls 명령을 -F 플래그를 포함하는 ls 버전으로 별칭을 지정했기 때문일 것입니다. 이 플래그는 각 출력 이름 (일반 파일이 아님)에 문자를 추가하여 그 종류를 나타냅니다. 따라서 하나의 슬래시는 '* /'패턴과 일치하는 from이고 다른 슬래시는 추가 된 유형 표시기입니다.

To get rid of this issue, you could of course define a different alias for ls. However, to temporarily not invoke the alias, you can prepend the command with backslash:

\ls -d */


I just add this to my .bashrc file (you could also just type it on the command line if you only need/want it for one session)

alias lsd='ls -ld */'

then lsd will produce the desired result.


Actual ls solution, including symlinks to directories

Many answers here don't actually use ls (or only use it in the trivial sense of ls -d, while using wildcards for the actual subdirectory matching. A true ls solution is useful, since it allows the use of ls options for sorting order, etc.

Excluding symlinks

One solution using ls has been given, but it does something different from the other solutions in that it excludes symlinks to directories:

ls -l | grep '^d'

(possibly piping through sed or awk to isolate the file names)

Including symlinks

In the (probably more common) case that symlinks to directories should be included, we can use the -p option of ls, which makes it append a slash character to names of directories (including symlinked ones):

ls -1p | grep '/$'

or, getting rid of the trailing slashes:

ls -1p | grep '/$' | sed 's/\/$//'

We can add options to ls as needed (if a long listing is used, the -1 is no longer required).

note: if we want trailing slashes, but don't want them highlighted by grep, we can hackishly remove the highlighting by making the actual matched portion of the line empty:

ls -1p | grep -P '(?=/$)'

If hidden directory is not needed to be listed, I offer:

ls -l | grep "^d" | awk -F" " '{print $9}'  

And if hidden directories is needed to be listed, use:

ls -Al | grep "^d" | awk -F" " '{print $9}'

OR

find -maxdepth 1 -type d | awk -F"./" '{print $2}'

to show folder lists without /

ls -d */|sed 's|[/]||g'

For listing only directories:

ls -l | grep ^d

for listing only files:

ls -l | grep -v ^d 

or also you can do as: ls -ld */


Here is what I am using

ls -d1 /Directory/Path/*;


Test whether the item is a directory with test -d:

for i in $(ls); do test -d $i && echo $i ; done

One-liner to list directories only from "here".

With file count.

for i in `ls -d */`; do g=`find ./$i -type f -print| wc -l`; echo "Directory $i contains $g files."; done

*/ is a filename matching pattern that matches directories in the current directory.

To list directories only, I like this function:

# long list only directories
llod () { 
  ls -l --color=always "$@" | grep --color=never '^d'
}

Put it in your .bashrc.

Usage examples:

llod       # long listing of all directories in current directory
llod -tr   # same but in chronological order oldest first
llod -d a* # limit to directories beginning with letter 'a'
llod -d .* # limit to hidden directories

NOTE: it will break if you use the -i option. Here is a fix for that:

# long list only directories
llod () { 
  ls -l --color=always "$@" | egrep --color=never '^d|^[[:digit:]]+ d'
}

FYI, if you want to print all the files in multi-line, you can do a ls -1 which will print each file in a separate line. file1 file2 file3


Using Perl:

ls | perl -nle 'print if -d;'

A plain list of the current directory, it'd be:

ls -1d ./*/

Do you want it sorted and clean?

ls -1d ./*/ | cut -c 3- | rev | cut -c 2- | rev | sort

Remember: capitalized characters have different behavior in the sort


Try this one. It works for all linux distros.

ls -ltr | grep drw

I partially solved with :

cd "/path/to/pricipal/folder"

for i in $(ls -d .*/); do sudo ln -s "$PWD"/${i%%/} /home/inukaze/${i%%/}; done

ln: «/home/inukaze/./.»: can't overwrite a directory
ln: «/home/inukaze/../..»: can't overwrite a directory
ln: accesing to «/home/inukaze/.config»: too much symbolics links levels
ln: accesing to «/home/inukaze/.disruptive»: too much symbolics links levels
ln: accesing to «/home/inukaze/innovations»: too much symbolics links levels
ln: accesing to «/home/inukaze/sarl»: too much symbolics links levels
ln: accesing to «/home/inukaze/.e_old»: too much symbolics links levels
ln: accesing to «/home/inukaze/.gnome2_private»: too much symbolics links levels
ln: accesing to «/home/inukaze/.gvfs»: too much symbolics links levels
ln: accesing to «/home/inukaze/.kde»: too much symbolics links levels
ln: accesing to «/home/inukaze/.local»: too much symbolics links levels
ln: accesing to «/home/inukaze/.xVideoServiceThief»: too much symbolics links levels

Well , this reduce to me , the mayor part :)


Adding on to make it full circle, to retrieve the path of every folder, use a combination of Albert's answer as well as Gordans that should be pretty usefull.

for i in $(ls -d /pathto/parent/folder/*/); do echo ${i%%/}; done

Output:

/pathto/parent/folder/childfolder1/
/pathto/parent/folder/childfolder2/
/pathto/parent/folder/childfolder3/
/pathto/parent/folder/childfolder4/
/pathto/parent/folder/childfolder5/
/pathto/parent/folder/childfolder6/
/pathto/parent/folder/childfolder7/
/pathto/parent/folder/childfolder8/

To answer the original question, */ has nothing to do with ls per se; it is done by the shell/Bash, in a process known as globbing.

This is why echo */ and ls -d */ output the same elements. (The -d flag makes ls output the directory names and not contents of the directories.)


file *|grep directory

O/P (On my machine) --

[root@rhel6 ~]# file *|grep directory
mongo-example-master:    directory
nostarch:                directory
scriptzz:                directory
splunk:                  directory
testdir:                 directory

Above output can be refined more by using cut .

file *|grep directory|cut -d':' -f1
mongo-example-master
nostarch
scriptzz
splunk
testdir

* could be replaced with any path that's permitted
 file - determine file type
 grep - searches for string named directory
 -d - to specify a field delimiter
 -f1 - denotes field 1

Here is what I use for listing only directory names:

ls -1d /some/folder/*/ | awk -F "/" "{print \$(NF-1)}"

Here is a variation using tree which outputs directory names only on seperate lines, yes it's ugly but hey, it works.

tree -d | grep -E '^[├|└]' | cut -d ' ' -f2

or with awk

tree -d | grep -E '^[├|└]' | awk '{print $2}'

This is probably better however and will retain the / after directory name.

ls -l | grep "^d" | awk '{print $9}'

The shortest command ever (actually a hack) for listing only directories. Type in absolute path or relative path of the directory of interest. Type cd and hit tab. Only the directories are shown.

$ cd 

Shortest indeed.

참고URL : https://stackoverflow.com/questions/14352290/listing-only-directories-using-ls-in-bash-an-examination

반응형