ls는 심볼릭 링크의 디렉토리 내용을 무시합니다.

ls는 심볼릭 링크의 디렉토리 내용을 무시합니다.

심볼릭 링크를 표시하지 않고 모든 것(파일 및 하위 디렉터리)을 나열하려는 디렉터리가 있습니다. 저는 Linux에서 GNU 유틸리티를 사용하고 있습니다. 버전은 ls8.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)을 수행하는 것입니다.

답변1

명시된 문제에 대해 다음을 사용할 수 있습니다.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이 파일 이름을 표시하도록 강제합니다.

답변2

또는 더 간단하게:

ls -l | grep -v ^l

설명하다

ls -l나열한다는 뜻이다긴 목록. 이렇게 하면 첫 번째 문자열이 각 파일에 대한 정보를 제공합니다. 첫 번째 문자는 각 파일의 유형을 나타냅니다. 기호 링크인 경우 an이 l첫 번째 문자입니다.

grep -v ^l-v( ) an으로 시작하는 ( ) 행을 필터링함을 나타냅니다 .^l

답변3

버전 2.12부터 -rGNU grep 옵션은 수동으로 지정하지 않는 한 기호 링크를 역참조하지 않습니다.

-r, --재귀

각 디렉토리 아래의 모든 파일은 기호 링크가 명령줄에 있는 경우에만 반복적으로 읽혀집니다. 이는 -d 재귀 옵션과 동일합니다.

-R, --역참조 재귀

각 디렉터리의 모든 파일을 재귀적으로 읽습니다. -r과 달리 모든 기호 링크를 따릅니다.

답변4

이 작업을 수행 하는 데 사용할 수 있습니다 $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=:구성 가능한 각 이름을 자체 값으로 삽입하고 슬래시 한두 개를 추가하는 방식으로 작동합니다. 물론 \0NUL 바이트도 작동합니다.

기본적으로 첫 번째 출력 바로 앞에 삽입 ls되지만 여기서는 정확하게 표시되지 않습니다. 이 경우에는 내가 지정했습니다.$rs$lc$ec (종료 코드)이는 모든 경우를 나타냅니다 . 이를 지정할 때 및 사이에 추가 정보를 얻을 수 $rs없습니다 . 파일 이름 뒤에만 나타납니다.$rs$no${type_code}그리고출력 시작 부분에 한 번 - 첫 번째 줄 시작 부분에 추가 슬래시가 하나 있는 것을 볼 수 있습니다.

이것은 나의 단편이다$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 -pcli에서 info dircolors더 많은 정보를 얻으 십시오 .

파일 이름을 임의의 문자열로 묶을 수 있습니다. 원하는 경우 주석을 달 수 있습니다. 파일 확장자만을 기준으로 유사한 동작을 지정할 수 있습니다. 이 방법으로는 지정할 수 없는 것이 없습니다.

이제 나도 이 말을 그냥 지어내는 것이 아니라 우연히 우연히 발견하고 있습니다.소스 코드우연히.

이 특정 구성을 사용하면 ls다음이 발생합니다.

  1. $no- 각 레코드의 시작 부분에 레코드당 한 번씩

  2. ${type_code}- 파일 형식의 약어를 포함하는 각 파일 이름 바로 앞에 항상 같은 줄에 표시되고 그 뒤에는 공백으로 구분된 7개의 필드가 옵니다.$no 또는->심볼릭 링크의 대상을 나타내는 직후 .

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

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

다음은 null로 구분된 것입니다 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파일 이름에 포함된 문자에 관계없이 출력에서 ​​원하는 파일 형식의 조합을 안정적으로 제거할 수 있어야 합니다 .

관련 정보