ls
디렉토리의 내용을 나열하기 위해 명령의 매개변수를 결합 하려고 합니다 . 내가 기본적으로 달성하려고 하는 것은 모든 링크를 역참조하는 디렉토리를 나열하지만 나열된 항목이 링크임을 명확하게 표시하는 것입니다. --dereference
및 옵션을 결합하려고 시도했지만 링크 대상이 실행 파일이기 때문에 --classify
링크 기호( ) 대신 이 표시 @
되었습니다 .*
어떻게 이런 결과를 얻을 수 있는지에 대한 아이디어가 있나요? ls
명령 이외의 옵션도 열려 있습니다 .
편집하다:
실제로 명령에서 다른 옵션을 사용했습니다 ls
. 내 현재 명령과 해당 옵션은 다음과 같습니다.
ls -ogq -LB --group-directories-first --time-style=long-iso
->
구축 중인 애플리케이션 내에서 출력을 구문 분석하려고 하는데 화살표( )가 있는 기본 링크 출력을 사용할 수 없습니다 . 폴더, 파일 등 디렉터리의 다른 항목도 나열되어야 합니다.
편집(2):
명확히 하기 위해 SSH2 API를 사용하여 서버에 연결하고 디렉터리를 나열하는 Java 애플리케이션을 개발 중입니다. 그런 다음 목록의 결과는 jsTree jQuery 플러그인을 사용하여 트리를 채우는 데 사용됩니다. 현재 위에서 인용한 명령은 다음과 같은 출력을 제공합니다.
felipe@simba:/mnt/drive$ ls -ogq --group-directories-first --time-style=long-iso
total 12
drwxr-sr-x 2 4096 2014-06-11 18:04 folder1
drwxr-sr-x 6 4096 2014-06-27 19:35 folder2
dr-Sr-s-wt 2 4096 2014-06-27 13:51 folderWithPermissions
-rw-r--r-- 1 0 2014-06-30 10:42 file.txt
lrwxrwxrwx 1 49 2014-06-30 11:36 linkTeste -> folder2/dir/otherfile.txt
정규식을 적용하면 권한을 확인하여 폴더, 파일 또는 링크가 무엇인지 식별할 수 있습니다. 하지만 링크가 있는 경우 대신 링크 이름만 나열하면 됩니다 . 명령의 옵션을 name -> destination
사용하면 링크 이름만 출력되고 참조된 대상의 권한을 얻게 됩니다(좋은 점입니다). 옵션 의 링크 참조를 해제했지만 링크가 실제로 연결인지 알 수 있는 방법이 없습니다.-L
ls
-L
felipe@simba:/mnt/drive$ ls -ogq -L --group-directories-first --time-style=long-iso
total 12
drwxr-sr-x 2 4096 2014-06-11 18:04 folder1
drwxr-sr-x 6 4096 2014-06-27 19:35 folder2
dr-Sr-s-wt 2 4096 2014-06-27 13:51 folderWithPermissions
-rw-r--r-- 1 0 2014-06-30 10:42 file.txt
-rwxr-xr-x 1 0 2014-06-27 18:40 linkTeste
링크 이름을 나열하고 그것이 링크인지, 대상이 무엇인지(파일, 폴더 또는 링크)를 알아야 합니다. 어쨌든 정규식을 적용하므로 다양한 유형의 출력을 처리할 수 있습니다.
find
또는 를 사용하는 대안 도 환영합니다 .stat
답변1
업데이트된 질문에 대한 응답으로 편집됨
링크, 디렉터리 및 일반 파일에만 관심이 있고 ls
인식되는 다른 파일 형식(FIFO, 소켓 등) 을 처리할 필요가 없으므로 stat
아래 예에서는 . 다음 테스트 환경:
$ ls -l
total 4.0K
-rw-r--r-- 1 terdon terdon 0 Jun 30 23:12 a new?line
-rw-r--r-- 1 terdon terdon 0 Jun 30 23:12 a space
-rw-r--r-- 1 terdon terdon 0 Jun 30 23:12 a?tab
drwxr-xr-x 2 terdon terdon 4.0K Jun 30 23:11 dir1
lrwxrwxrwx 1 terdon terdon 4 Jun 30 23:13 linktodir1 -> dir1
lrwxrwxrwx 1 terdon terdon 7 Jun 30 23:13 sh -> /bin/sh
보시다시피 여기에는 링크, 실행 파일에 대한 링크, 공백이 있는 파일 이름, 탭이 있는 파일 이름( ), \t
줄바꿈( )이 있는 \n
파일 이름이 포함됩니다. 이러한 파일의 대부분은 ls
메서드를 손상시키지만 stat
올바르게 처리할 수 있습니다.
$ stat --printf "%A\t%N\t%F\n" *
-rw-r--r-- ‘a new\nline’ regular file
-rw-r--r-- ‘a space’ regular file
-rw-r--r-- ‘a\ttab’ regular file
drwxr-xr-x ‘dir1’ directory
lrwxrwxrwx ‘linktodir1’ -> ‘dir1’ symbolic link
lrwxrwxrwx ‘sh’ -> ‘/bin/sh’ symbolic link
관련 부품 man stat
:
--printf=형식
--format과 비슷하지만 백슬래시 이스케이프가 해석되고 강제로 후행 줄 바꿈이 출력되지 않습니다. 개행 문자를 원하면 FORMAT에 \n을 포함하세요.
%사람이 읽을 수 있는 액세스 권한 형식
%F 파일 형식
%N 인용된 파일 이름, 심볼릭 링크인 경우 인용되지 않음
필드는 구분되어 있으므로 \t
필드의 공백(예: 파일 이름의 공백)을 적절하게 처리할 수 있습니다.
당신은 대처할 수 없다고 언급했습니다 ->
. 왜 그런지는 잘 모르겠지만 사용할 수 있습니다.sed
$ stat --printf "%A\t%N\t%F\n" * | sed 's/->//'
lrwxrwxrwx ‘linktodir1’ ‘dir1’ symbolic link
아니면 다른 문자열로 바꾸세요:
$ stat --printf "%A\t%N\t%F\n" * | sed 's/->/→/' | grep linktodir
lrwxrwxrwx ‘linktodir1’ → ‘dir1’ symbolic link
아니면 파일 형식을 구문 분석하면 됩니다.
수행하려는 작업에 따라 검색 중인 세 가지 파일 형식을 분리하여 개별적으로 처리하는 것이 유용할 수 있습니다. 그렇다면 find
1 과 해당 -printf
옵션을 사용하십시오.
$ find ./ -maxdepth 1 -mindepth 1 -type f -printf '%M\t%P\t%l\n' ## files
$ find ./ -maxdepth 1 -mindepth 1 -type d -printf '%M\t%P\t%l\n' ## directories
$ find ./ -maxdepth 1 -mindepth 1 -type l -printf '%M\t%P\t%l\n' ## links
이 경우 printf
지시사항은 다음과 같습니다.
%M File's permissions (in symbolic form, as for ls). This
directive is supported in findutils 4.2.5 and later.
%P File's name with the name of the command line argument
under which it was found removed.
%l Object of symbolic link (empty string if file is not a
symbolic link).
위의 명령을 단일 명령으로 결합할 수도 있지만( find
' 연산자 사용), 파일 유형에 따라 임의의 문자열을 인쇄할 -o
수 있습니다 . -printf
예를 들어:
$ find ./ -maxdepth 1 -mindepth 1 \( -type l -printf 'link:\t%M\t%P\t%l\n' \) \
-o \( -type d -printf 'dir:\t%M\t%P\n' \) \
-o \( -type f -printf 'file:\t%M\t%P\n' \)
file: -rw-r--r-- a?tab
file: -rw-r--r-- a space
link: lrwxrwxrwx linktodir1 dir1
file: -rw-r--r-- a new?line
dir: drwxr-xr-x dir1
link: lrwxrwxrwx sh /bin/sh
위 명령의 출력이 터미널에 표시되지 않으면 명령이 올바르게 해석됩니다 \t
. \n
그러나 개행 문자가 포함된 파일 이름을 적절하게 처리하려면 구문 분석할 때 주의하거나("line"이 로 시작하는지 확인 [file|dir|link]:
) 대신 \0
각 호출에서 줄 종결자로 사용해야 합니다 .printf
\n
$ find ./ -maxdepth 1 -mindepth 1 \( -type l -printf 'link:\t%M\t%P\t%l\0' \) \
-o \( -type d -printf 'dir:\t%M\t%P\0' \) \
-o \( -type f -printf 'file:\t%M\t%P\0' \)
1 -maxdepth
이고 -mindepth
GNU 확장이므로 이 방법은 GNU에서만 작동합니다 find
.
다음은 문제의 덜 구체적인 첫 번째 버전에 대한 솔루션으로 게시되었습니다. 다른 사람들에게 유용할 수 있기 때문에 여기에 남겨 두겠습니다.
쉘과
readlink
for f in *; do readlink "$f" >/dev/null && echo "$(readlink -f "$f") (link)" || echo "$f"; done
출력 예:
/etc (link) foo sample.R sample.R~
위의 루프는 현재 파일 및 디렉터리 아래의 모든 파일 및 디렉터리를 반복하고 성공을 반환하면 ( 링크의
readlink
경우 ) 이를 역참조합니다( , 다음 내용에 유의하세요.$f
readlink -f
모두링크. 첫 번째 레벨만 필요한 경우 이를 제거-f
하고 해당 레벨로 대상을 인쇄하십시오(link)
. 그렇지 않은 경우에는 그냥 인쇄됩니다$f
.이것이 귀하만을 위한 것이며 구문 분석할 의도가 없는 경우 다음을 사용하십시오
ls -l
.$ ls -l total 512116 -rw-r--r-- 1 terdon terdon 100641 Jun 30 19:10 er lrwxrwxrwx 1 terdon terdon 5 Jun 30 19:12 etc -> /etc/ -rw-r--r-- 1 terdon terdon 524288000 Jun 30 19:10 foo -rwxr--r-- 1 terdon terdon 353 Jun 30 15:22 sample.R -rwxr--r-- 1 terdon terdon 249 Jun 30 14:51 sample.R~
그러면 와의 링크가 명확하게 표시됩니다
link -> target
.