심볼릭 링크를 무시하는 디렉토리의 ls 내용


17

심볼릭 링크를 표시하지 않고 모든 내용 (파일 및 하위 디렉토리)을 나열하려는 디렉토리가 있습니다. Linux에서 GNU 유틸리티를 사용하고 있습니다. ls버전은 8.13이다.

예:

전체 디렉토리 목록 :

~/test$ ls -Gg
total 12
drwxrwxr-x 2 4096 Jul  9 10:29 dir1
drwxrwxr-x 2 4096 Jul  9 10:29 dir2
drwxrwxr-x 2 4096 Jul  9 10:29 dir3
-rw-rw-r-- 1    0 Jul  9 10:29 file1
-rw-rw-r-- 1    0 Jul  9 10:29 file2
lrwxrwxrwx 1    5 Jul  9 10:29 link1 -> link1
lrwxrwxrwx 1    5 Jul  9 10:30 link2 -> link2

내가 얻고 싶은 것

~/test$ ls -somthing (or bash hack)
total 12
dir1 dir2 dir3 file1 file2

참고 : 나의 주요 동기는 심볼릭 링크를 따르지 않고 재귀 grep (GNU grep 2.10)을 수행하는 것입니다.

답변:


28

명시된 질문에 대해 다음을 사용할 수 있습니다 find.

find . -mindepth 1 ! -type l

현재 디렉토리 또는 심볼릭 링크가 아닌 하위 디렉토리의 모든 파일과 디렉토리를 나열합니다.

mindepth 1.현재 디렉토리 항목 을 건너 뛰는 것 입니다. 그것의 고기는 -type l"심볼릭 링크" !를 의미하는 , 및 다음 테스트를 무효화 한다는 의미 의 조합입니다 . 조합하여 심볼릭 링크가 아닌 모든 파일과 일치합니다. 이것은 모든 파일과 디렉토리를 재귀 적으로 나열하지만 심볼릭 링크는 없습니다.

디렉토리가 아닌 일반 파일을 원할 경우 :

find . -type f

이 디렉토리의 직접 하위 만 포함하고 나머지는 재귀 적으로 포함하지 않습니다.

find . -mindepth 1 -maxdepth 1

이러한 (및 다른) 테스트를 결합하여 원하는 파일 목록을 얻을 수 있습니다.

grep사용중인 테스트와 일치하는 모든 파일 에서 특정을 실행하려면 -exec다음을 사용하십시오 .

find . -type f -exec grep -H 'some pattern' '{}' +

'{}'파일로 대체됩니다. 은 +말할 필요가 find당신의 명령을 수행합니다. 이 옵션 -H은 grep이 일치하는 단일 파일로 실행 되더라도 파일 이름을 표시하도록합니다.


패턴이 발견 된 파일을 마녀에 표시하지 않습니다.
TheMeaningfulEngineer

그것이 당신이 실행하는 것 grep입니다 (마지막 단락 참조).
마이클 호머

나는 나를 위해 작동하지 않습니다. 찾은 파일 이름없이 찾은 패턴을 출력합니다.
TheMeaningfulEngineer

2
을 사용하는 grep -H경우 (참조 man grep) 또는 그렇지 않은 grep 'pat' '{}' /dev/null ';'경우 여러 파일이 있다고 생각하도록 속이십시오.
마이클 호머

1
+마지막에 하나의 파일 또는 하나의 파일 만 남아있는 퇴보 된 경우 해당 요구 사항을 충족하지 못합니다.
마이클 호머

16

또는 더 간단합니다.

ls -l | grep -v ^l

설명

ls -l긴 형식 으로 나열하는 것을 의미합니다 . 이렇게하면 첫 번째 문자열이 각 파일에 대한 정보를 제공합니다. 첫 번째 문자는 각 파일의 유형을 나타냅니다. 심볼릭 링크 인 경우 an l이 첫 번째 문자입니다.

grep -v ^l-v시작하는 행 을 필터링 ( )하는 것을 의미 ^합니다 l.


이것은 훌륭하지만 폴더 이름 만 얻는 방법은 무엇입니까? 나는 이것을 이것을 사용하고 싶다for i in
Luka

이 코드를 설명해 주시겠습니까?
abg

생략하면이 솔루션이 작동하지 않습니다 -l.ls . 따라서 이것은 예상대로 작동하지 않을 것입니다 :ls | grep -v ^l
stamster

@Luka 당신은 출력을 반복하지 않습니다 find unix.stackexchange.com/questions/321697
Kusalananda를

1
@abg-설명을 추가했습니다. 도움이 되길 바랍니다.
Geoff

7

버전 2.12부터 -rGNU grep 옵션은 사용자가 직접 지정하지 않는 한 심볼릭 링크를 역 참조하지 않습니다.

-r,-재귀

명령 행에있는 경우에만 기호 링크를 따라 각 디렉토리 아래의 모든 파일을 재귀 적으로 읽으십시오. 이것은 -d recurse 옵션과 동일합니다.

-R,-역 참조 재귀

각 디렉토리 아래의 모든 파일을 재귀 적으로 읽으십시오. -r과 달리 모든 기호 링크를 따르십시오.


그렙의 버전은 무엇입니까? 나는 -R, -r, --recursive Read all files under each directory, recursively; this is equivalent to the -d recurse option.2.10에있다
TheMeaningfulEngineer

grep (GNU grep) 2.14
tijagi

5

zsh에서는 glob 한정자 덕분에 쉽게 사용할 수 있습니다 .

grep -- PATTERN **/*(.)

패턴 **/은 서브 디렉토리를 재귀 적으로 탐색합니다. glob 한정자 .는 일반 파일과의 일치를 제한합니다.

zsh가 없으면 사용 find하십시오 ( Michael Horner의 답변 참조 ). 이 특별한 경우 GNU grep은 원하는 것을 수행 할 수 있습니다 (정확히하는 것 grep -r). 2.12 버전 이후에만 이전 버전은 심볼릭 링크를 따랐습니다.


2

이를 위해 사용할 수 있습니다 $LS_COLORS. 해당 버전을 ls사용하여 해당 변수를 사용하여 색상 지정 을 지원하는 경우 파일 유형별로 출력을 정의 할 수 있습니다. 기본 동작이며 매우 구성 가능합니다. 그래서 다음과 같이 데모 할 파일을 만들었습니다.

for f in 9 8 7 6 5 4 3 2 1
    do touch "${f}file" && 
    ln -s ./"${f}file" ./"${f}filelink"
done

이제 할게요 :

LS_COLORS='lc=:rc=:ec=:ln=\n\n\0HERE_THERE_BE_A_LINK>>\0:' \
ls -1 --color=always | cat

###OUTPUT###
1file


HERE_THERE_BE_A_LINK>>1filelink@
2file


HERE_THERE_BE_A_LINK>>2filelink@
3file

...
HERE_THERE_BE_A_LINK>>8filelink@
9file
...

그리고 null도 있습니다 ...

LS_COLORS='lc=:rc=:ec=:ln=\n\n\0HERE_THERE_BE_A_LINK>>\0:' \
ls -1 --color=always | sed -n l
1file$
$
$
\000HERE_THERE_BE_A_LINK>>\0001filelink@$
2file$
$
$
\000HERE_THERE_BE_A_LINK>>\0002filelink@$
3file$
...

모든 또는 모든 파일 형식을 지정할 수 있습니다. ls터미널 이스케이프에 대한 기본 컴파일 값이 일부 포함되어 있기 때문에 단일 파일 유형에 대해서만 그렇게하는 것은 원하지 않을 수 있습니다 . API를 단일 인터페이스로 처리하는 것이 훨씬 낫습니다. 현재 환경 dircolors구성 기본값 을 구문 분석하고 할당하는 간단한 방법은 다음과 같습니다 .

LS_COLORS='rs=:no=//:lc=:rc=:ec=//:'$(
set -- di fi ln mh pi so do bd cd or su sg ca tw ow st ex
for fc do printf %s "$fc=/$fc//:"
done) ls -l --color=always | cat

내 홈 디렉토리의 출력은 다음과 같습니다.

total 884
///-rw-r--r-- 1 mikeserv mikeserv    793 Jul  9 11:23 /fi//1/
//drwxr-xr-x 1 mikeserv mikeserv    574 Jun 24 16:50 /di//Desktop//
//-rw-r--r-- 1 mikeserv mikeserv    166 Jul  4 23:02 /fi//Terminology.log/
//-rw-r--r-- 1 mikeserv mikeserv      0 Jul  6 11:24 /fi//new
file/
//lrwxrwxrwx 1 mikeserv mikeserv     10 Jul 11 04:18 /ln//new
file
link/ -> /fi//./new
file/
//-rwxr-xr-x 1 mikeserv mikeserv    190 Jun 22 11:26 /ex//script.sh/*
//-rw-r--r-- 1 mikeserv mikeserv 433568 Jun 22 17:10 /fi//shot-2014-06-22_17-10-16.jpg/
//-rw-r--r-- 1 mikeserv mikeserv     68 Jun 17 19:59 /fi//target.txt/

당신도 그것을 실행할 수 있으며 cat -A당신이 보게 될 유일한 차이점은 줄 $바꿈 을 볼 수 있다는 것 입니다- ls --color=always이 구성으로 소개 할 ​​수없는 문자가 없습니다 -여기에 보이는 것만 있습니다.

ls 다음과 같이 기본 터미널 이스케이프를 삽입합니다.

${lc}${type_code}${rc}FILENAME${lc}${rs}${rc}

... $lc (왼쪽 코드) , $rc (오른쪽 코드)$rs (재설정) 의 기본값 은 다음과 같습니다.

 \033 - ESCAPE
 m - END ESCAPE
 0 - reset 

...각기. ${type_code}다양한 fi (일반 파일-기본 설정 해제) , di (디렉토리) , ln (링크) 및 내가 알고있는 다른 모든 파일 형식을 나타내는 데 사용됩니다. 도 있습니다 $no (정상) 기본적으로도 해제하고있는 여기에 의해 표현되는 //각 행의 시작 부분은. 내 간단한 작은 IFS=:블록은 구성 가능한 각 이름을 자체 값으로 삽입하고 슬래시 또는 2를 추가하여 작동하지만 \0NUL 바이트도 마찬가지입니다.

기본적 으로 첫 번째 출력 바로 앞에 ls하나를 삽입 $rs합니다$lc 하지만 여기에 정확하게 표시되지는 않습니다. 이 경우 내가 지정한 $ec (종료 코드) 에 대한에 서 $rs모든 경우에 -이 지정되어있을 때 추가하지 않는 $rs사이 $no${type_code}그것을 유일한 선물은 바로 파일 이름을 다음 - 당신이 다른 것 같은 출력의 시작에 한 번을 -1 행에서 한 번의 추가 슬래시에서 볼 수 있듯이.

여기 내 스 니펫이 있습니다. $LS_COLORS

printf %s "$LS_COLORS"

rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:\
so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:\
or=40;31;01:su=37;41:sg=30;43:ca=30;41:\
tw=30;42:ow=34;42:st=37;44:ex=01;32:\
*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:...

사실, 내 작은 쉘 핵은 지나치게 복잡 할 수 있습니다. 이러한 값을 할당하기 위해 광범위하게 사용 가능한 인터페이스가 있습니다. dircolors -p당신의 진료소에서 시도 하고info dircolors 자세한 정보를 확인하십시오.

파일 이름을 임의의 문자열로 줄 바꿈 할 수 있습니다. 원하는 경우 의견을 제시 할 수 있습니다. 파일 확장자만으로 유사한 동작을 지정할 수 있습니다. 그렇게 지정할 수없는 것은 많지 않습니다.

이제 나는이 모든 것을 만들어내는 것이 아니라 소스 코드를 우연히 만난 후에 그것에 대해 배웠습니다. . 우연히 를 우연히 .

이 특정 구성으로 ls 을 방출합니다.

  1. $no -각 레코드 시작시 레코드 당 한 번

  2. ${type_code}- 한 번에 바로 파일의 형식의 약어를 포함하는 각 파일 이름을 이전과 이후 필드를 구분 공백으로 7 항상 같은 라인에서 발생 $no 또는 즉시 다음-> 있으며 심볼릭 링크의 대상을 나타내는 나타 .

  3. $ec -첫 번째 줄 바로 앞에 한 번, 그 후에 각 파일 이름 바로 뒤에 한 번만.

  4. 다른 모든 값은 비어 있습니다.

다음은 null-delimited ls이며 이번에는을 사용 cat -A하지만 마지막 예제와 동일 하게 사용할 것입니다.

LS_COLORS='rs=:no=\0//:lc=:rc=:ec=\0//:'$(
set -- di fi ln mh pi so do bd cd or su sg ca tw ow st ex
for fc do printf %s "$fc=/$fc//\0:"
done) ls -l --color=always | cat -A

total 884$
^@//^@//-rw-r--r-- 1 mikeserv mikeserv    793 Jul  9 11:23 /fi//^@1^@//$
^@//drwxr-xr-x 1 mikeserv mikeserv    574 Jun 24 16:50 /di//^@Desktop^@///$
^@//-rw-r--r-- 1 mikeserv mikeserv    166 Jul  4 23:02 /fi//^@Terminology.log^@//$
^@//-rw-r--r-- 1 mikeserv mikeserv      0 Jul  6 11:24 /fi//^@new$
file^@//$
^@//lrwxrwxrwx 1 mikeserv mikeserv     10 Jul 11 04:18 /ln//^@new$
file$
link^@// -> /fi//^@./new$
file^@//$
^@//-rwxr-xr-x 1 mikeserv mikeserv    190 Jun 22 11:26 /ex//^@script.sh^@//*$
^@//-rw-r--r-- 1 mikeserv mikeserv 433568 Jun 22 17:10 /fi//^@shot-2014-06-22_17-10-16.jpg^@//$
^@//-rw-r--r-- 1 mikeserv mikeserv     68 Jun 17 19:59 /fi//^@target.txt^@//$

따라서 이와 같은 전체 목록 에서 모든 심볼릭 링크 를 안정적으로 제거 -l하려면 간단한 변경을 수행 할 수 있습니다.

LS_COLORS='rs=:no=//:lc=:rc=:ec=/ :'$(
set -- di fi mh pi so do bd cd or su sg ca tw ow st ex
for fc do printf %s "$fc=$fc/:"
done)ln=///: ls -l --color=always | sed ':ln
\|///|{N;\|\n//|!bln};s|.*//||'

실행 후 내 결과는 다음과 같습니다 ...

total 884
-rw-r--r-- 1 mikeserv mikeserv    793 Jul  9 11:23 fi/1/ 
drwxr-xr-x 1 mikeserv mikeserv    574 Jun 24 16:50 di/Desktop/ /
-rw-r--r-- 1 mikeserv mikeserv    166 Jul  4 23:02 fi/Terminology.log/ 
-rw-r--r-- 1 mikeserv mikeserv      0 Jul  6 11:24 fi/new
file/ 
-rwxr-xr-x 1 mikeserv mikeserv    190 Jun 22 11:26 ex/script.sh/ *
-rw-r--r-- 1 mikeserv mikeserv 433568 Jun 22 17:10 fi/shot-2014-06-22_17-10-16.jpg/ 
-rw-r--r-- 1 mikeserv mikeserv     68 Jun 17 19:59 fi/target.txt/ 

위에서하는 것과 비슷한 명령을 사용합니다.

LSCOLORS=...$(...)fc1=///:fc2=///: ls ... | sed ...

... ( 서브 쉘에서 뒤에 나열된 파일 유형 fc1및 위치 )fc2set --ls파일 이름에 포함될 수있는 문자에 관계없이 출력 에서 원하는 파일 유형 조합을 안정적으로 제거하는 역할을 합니다.


기쁘다, 독창성을 위해 +1. 디렉토리에 질식하는 것처럼 보이지만 ANSI 색상 코드가 잘못 인쇄되어 있습니다. 어쨌든, 이것이 어떻게 작동하는지에 대한 설명을 추가 할 수 있습니까? 아마도 무엇인지 설명 lc, nc등인가?
terdon

@terdon-환경에 이미 설정된 ANSI 이스케이프로만 인쇄되거나 기본값으로 컴파일됩니다. lsdi=값에 . di=:무효화하려면 var 에 추가해야합니다 . 그것은 API의 의미입니다-각 파일 형식을 지정하지만 모든 경우에 인터페이스를 동일하게 지정해야합니다. 따라서 ln한 가지 방법으로 설정 하고 di기본값을 무시해도 문제 가 해결되지 않습니다. 많은 기본값이 컴파일되어 있습니다 ... 흠. 에 대해 물어 lcnc물건이 유효는 - 완전히 - 나는 이미 그것을하지만 다른 일을했다. 연결하겠습니다.
mikeserv

그렇기 때문에 가능한 모든 파일 형식을 항상 지정하거나 미리 존재하는 파일을 확인해야합니까? 알았어 고마워.
terdon

@terdon-지금 편집을 참조하십시오-두 줄의 셸로 모든 유형을 유형 이름으로 지정하고 모든 파일 이름을 안정적으로 구분합니다. 소개 된 인쇄 할 수없는 것도 없습니다. 어쨌든 API가 있습니다.dircolors 있습니다. 구성 파일을 읽고 쉘 eval친화적 인 var 값을 출력 합니다. 꽤 쉽지만 몇 줄이 있습니다. 어쨌든, 사용하고 dircolors싶다면 두 개의 다른 파일을 저장하고 그런 식으로 호출하십시오. 또한 요즘 \0에는 각 이스케이프 시퀀스의 일부로 NUL 구분 기호를 사용 하여 한 번에 두 가지를 모두 수행하는 방법을 보여주었습니다 .
mikeserv

@terdon-나는 컴파일 될 수있는 모든 값을 설정하는 것이 얼마나 쉬운 지 더 명확하게하려고 노력했다.-나는 아마도 너무나 많은 것으로 생각된다. LS_COLORS='rs=:no=\0//:lc=:rc=:ec=\0//:'$( set -- di fi ln mh pi so do bd cd or su sg ca tw ow st ex; for fc do printf %s "$fc=/$fc//\0:"; done) ls -l --color=always | cat -A
mikeserv

0

위의 대답은 다음과 같습니다.

 ls -1F | grep -i "/"

이상하게도 ls 명령에서 1을 그대로두면 여전히 목록이 제공됩니다.


1
grep -i? /대문자 또는 소문자 일 수는 없습니다 . ls출력이 터미널이 아닌 경우 (이것은 파이프 임) 기본적으로 noe-column 형식입니다.
Kusalananda

-2

이걸로 해봐:

ls | grep -v " -> "

2
예를 들어라는 파일에서 여러 가지 이유로 실패합니다 a -> b. 또한 줄 바꿈 및 기타 이상한 점이있는 파일 이름에서는 실패합니다. 읽어 보시기 바랍니다 LS를 구문 분석하는 것은 나쁜 생각하는 이유에 대해.
terdon

@terdon 이것이 실패하는 더 근본적인 이유가 있습니다. 의 ls별칭이 지정되어 ls -l파일 이름 앞에 열을 반환하거나 그렇지 않은 경우 기호 링크에 대해 특별한 작업을 수행하지 않습니다.
Gilles 'SO- 악마 그만해'

@terdon- ls자체 구문 분석합니다. 우리 ls는 터미널에 인쇄 할 때마다 모두 구문 분석 합니다 . api가 있습니다. 나는 여기에 비슷한 것을 보여주는 답변을 게시했지만 더 많은 것을 할 수 있습니다. 나는 당신에게 요일을 보여주었습니다. 널로 구분 된 파일 이름을 가지고있었습니다.
mikeserv

@mikeserv 알고 있습니다. 그러나이 작업을 수행하는 방법을 설명하려면 수백 줄이 필요합니다. 이 답변은 파싱의 모든 위험을 겪고 있으며 OP는 분명히 알지 못합니다.
terdon

@ terdon- ls당신의 아이들이나 아무것도 먹지 않을 것입니다-그것은 단지 프로그램 일뿐입니다. 당신이 다음을 설명하지 않는 경우는 것입니다 그것을 설명하기 위해 수백을 하고 당신은 단지에 연결된 수백 라인이 잘못된 이유보다 수백 설명 할 수 있습니다. 게다가 – 이것은 단지 두 줄입니다 :LS_COLORS='lc=:rc=:ec=:ln=\n\n\0HERE_THERE_BE_A_LINK>>\0:' \ ls -1 --color=always | cat
mikeserv

-3

이 명령을 시도하십시오 : ls -p | grep -v @


아니요, 링크를 나열합니다.
TheMeaningfulEngineer

@Alan : k 시도해보세요find -type f
Thushi

1
-1 이유 : i) -p디렉토리에 슬래시를 추가하면 -Fii) find대안이 디렉토리를 나열하지 않으며 iii) 게시하기 전에 답변을 테스트 하십시오.
terdon
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.