' ls -1 ' : 확장자없이 파일 이름을 나열하는 방법

ls -1는 내 요소를 다음과 같이 나열합니다.

foo.png bar.png foobar.png ... 

예 :

foo bar foobar ... 

(디렉터리에는 .png 파일 만 포함됨)

누군가이 경우 grep를 사용하는 방법을 알려줄 수 있습니까?

목적 : 모든 이름이없는 텍스트 파일이 있습니다. 신장. 텍스트 파일과 폴더를 비교하여 누락 된 파일이 무엇인지 확인하는 스크립트를 만들고 싶습니다.

댓글

  • 주의해야합니다. 이와 같은 요청. Linux에는 파일 이름 확장자가 없습니다. Linux에는 .가 포함되거나 포함되지 않을 수있는 파일 이름이 있습니다. 관례에서는 끝에 .png로 파일 이름을 지정하도록되어 있지만 ‘라는 이름의 png 파일을 가질 수없는 이유가 없습니다. foo.zip 또는 my.picture.20160518 또는 mypic.
  • @hymie I 알지만 그 폴더의 요소는 모두 끝에 .png로 이름이 지정됩니다.
  • 무엇이 ‘가 ” 확장자 “? ‘는 Unix 파일 이름 지정의 일부가 아닙니다. VMS / NT / Windows 무엇이든간에 ‘ 이월됩니다. 그리고 여러분도 제 잔디밭에서 내려옵니다. 🙂
  • ‘이 이것을 과장하지 않도록합니다. OS는 확장을 단순히 파일 이름의 일부로 취급하지만 많은 유닉스 프로그램이 컴파일러에서 GUI에 이르기까지 확장에주의를 기울입니다. 이 개념은 유닉스와는 전혀 다른 것이 아닙니다.
  • 일반적으로 ls lsfind의 출력을 파이프하는 것은 주로 ,`파일 이름에 탭 문자가 있습니다. 파일 이름이 The new art of working on .png\NEWLINE files and other formats이면 제안 된 많은 솔루션이 문제를 일으킬 것입니다.

답변

이 작업에는 셸만 필요합니다.

POSIXly :

for f in *.png; do printf "%s\n" "${f%.png}" done 

zsh :

print -rl -- *.png(:r) 

댓글

  • 저기 ‘는 printf가 필요하지 않습니다. echo ${f%.png}이면 충분합니다.
  • @Conrad : echo won ‘ 사용하면 파일 이름이 제대로 작동하지 않는 경우가 있습니다. 대시로 시작하거나 이스케이프 된 시퀀스를 포함합니다.
  • @DavidConrad : unix.stackexchange.com/a/65819/38906 li도 참조하세요. >
  • @DavidConrad 또한, 에코처럼 printf가 내장되어 있다고 믿습니다. ‘ 틀린 경우

Answer

ls -1 | sed -e "s/\.png$//" 

sed 명령은 제거 (즉, 빈 문자열로 대체) 에있는 모든 문자열 .png 파일 이름입니다.

.\.로 이스케이프되므로 를 정규식 . 대신 리터럴 . 문자 (즉, 모든 채널과 일치 함을 의미) aracter). $는 줄 끝 앵커이므로 파일 이름 중간의 .png와 일치하지 않습니다.

댓글

  • OP에서 모든 확장 프로그램을 제거하기를 원하지만 아마도 ” 마지막 질문 “. 따라서 다른 좋은 답변을 다음과 같이 수정할 수 있습니다. sed 's/\.[^.]*$//'
  • 예, 해당 정규 표현식은 이 경우에 작동하지만 OP가 원하는 경우에는 ” .png없이 나열되기를 원한다고 말하는 대신 그렇게 말해야합니다. ”
  • -1는 필요하지 않으며 여기서 기본값입니다.
  • @jlliagre -1를 지정해야합니다. ‘ 파이프를 켰을 때만 기본값이되므로 일부에게는 숨겨진 놀라움입니다. 따라서 명시 적으로 작성하면 도움이됩니다. 스크립트에서도이 작업을 수행하므로 어떤 종류의 utput I ‘ 예상합니다.
  • 경고 키가있는 파일 이름의 경우 (.png) 개행 문자 앞에 마지막 문자뿐만 아니라 .png도 지울 것입니다. ls의 출력을 파이프하고 구문 분석하는 것을 피하는 것이 더 낫습니다. 종종 잘 숨겨진 놀라움을 예약합니다 … (답에 더 많은 단어와 참조).

답변

bash를 사용하려는 경우 :

for i in *; do echo "${i%.png}"; done 

sed가 일치하는 항목을 제거 / 대체하는 것이 아니라 grep에 도달해야합니다. 더 적절 함 :

find . -maxdepth 1 -name "*.png" | sed "s/\.png$//" 

PNG 파일에서 순서를 가져 오기 위해 몇 가지 하위 디렉토리를 만들어야한다고 결정하면 다음과 같이 쉽게 변경할 수 있습니다.

find . -name "*.png" | sed "s/\.png$//" 

댓글

  • ls -1 | sed ‘ s / .png // ‘는 훌륭하게 작동합니다. 감사합니다!
  • find에서 sed 파이프 하면 몇 가지 문제가 발생할 수 있습니다. 이름의 일부로 개행 문자 바로 앞에 키 (.png)가있는 파일을 찾습니다. find 또는 ls의 출력을 파이프하고 구문 분석하는 것을 피하는 것이 좋습니다. 종종 잘 숨겨진 놀라움을 예약합니다 … (일부 단어 답변에서 더 많은 참조).
  • 아마 마지막 예에서 findecho와 같은 것으로 대체 할 수 있습니다. find가 어떤 용도로 사용되는지 명확하지 않으며 결과는 디렉토리 구조에 따라 다릅니다 (예 : 디렉토리가 files.png 인 경우)
  • @BroSlow 좀 더 현명한 것으로 업데이트되었습니다.

답변

또 다른 매우 유사한 답변입니다. 특정 변형이 아직 나타나지 않음) :

ls | sed -n "s/\.png$//p" 
  • -1가 필요하지 않습니다. ls에 대한 옵션입니다. ls는 표준 출력이 “ta 터미널 (이 경우”파이프) “이라고 가정하기 때문입니다.
  • -n sed 옵션은 기본적으로 행을 인쇄하지 않음을 의미합니다.
  • 대체 끝에있는 /p 옵션은 … 대체가 이루어진 경우이 줄을 인쇄합니다를 의미합니다.

그물 그 결과 .png로 끝나는 행만 제거됨. 즉, 이는 디렉토리에 .png 파일 만 포함되어 있지 않은 OP의 질문을 약간 일반화합니다.

sed -n 기술은 grep + sed를 사용할 수있는 경우에 종종 유용합니다.

댓글

  • 관리 방법이 마음에 듭니다. 답변을 작성하는 데 사용했습니다.이 솔루션은 newlines 를 포함한 파일 이름에 문제를 일으키며 이름의 첫 부분을 인쇄하지 않습니다. 키 (.png) 개행 문자 앞에 :이 경우 마지막 부분 만 지우지 않고 png없이 해당 부분을 인쇄합니다.

    생각하지 않는 곳에 문제를 숨길 수 있기 때문에 …

  • @Hastur You ‘ 맞습니다. , 원칙적으로 don ‘ t parse ls 는 병리학 적 파일 이름을 처리 할 때 추가 문제 (및 솔루션)를 나열합니다. 그러나이를 처리하는 가장 좋은 방법은 병리학 적 파일 이름을 사용하지 않는 (doh!); 그리고 ‘ t 할 수 있거나 이에 대해 반드시 견고해야한다면 find를 사용하거나 – 아마도 더 나은 – sh보다 더 강력한 언어를 사용하여 관리하십시오 (sh 할 수 있습니다 모든 것이 ‘ 각 경우에 ‘가 최선의 선택임을 의미하지는 않습니다. 쉘은 먼저 사용성을 위해 설계되었습니다.
  • 원칙적으로 사용성에 대해 동의하지만,이 변형은 각 줄 바꿈이있는 파일 이름 이 있으면 실패합니다. 예를 들어 GUI의 pdf에서 한 줄을 복사하여 붙여 넣을 때 눈에 띄지 않게 쉽게 발생할 수 있으므로 병적 파일 이름 은 피해야한다고 생각합니다.
  • 더욱 IMHO ls 파싱을 시작하는 것은 쉽지만 향후 문제가 될 것입니다. 종종 스크립트를 만듭니다. 나중에 사용할 것입니다. 이미 한계를 잊었을 때 … (‘ 인간이고 ‘ 보통입니다). 나는 find 예를 제안 했습니다 (-exec 포함 및 파이프 제외). (순수 쉘이기 때문에) 더 나은 것으로 간주 되더라도 cuonglm ‘ s one 에 답하고 견고하고 posix를 준수합니다.
  • 이것은 내가 ‘ 어떤 이유로 든 .png 파일 이름 목록에서 접미사.저는 ‘ 스크립트에 넣지 않을 것입니다. 대신 ‘ 쉘 프롬프트에서 명령을 입력하기 만하면됩니다. 이렇게하면 ‘ 가정 ” 정상적 ” 파일 이름. 일회성 수동 명령으로 ‘ 할 일이 많이 있습니다. ‘에 대해 자유롭게 가정 할 수 있습니다. 현재 디렉토리에서 다른 컨텍스트에서 재사용 될 수있는 스크립트에서는 ‘하지 않을 것입니다.

답변

basename (GNU 구현 가정) :

basename --suffix=.png -- *.png 

코멘트

  • 파이프에서 사용하려는 경우 GNU 기본 이름을 사용하는 것이 도움이 될 수 있습니다. ‘의 -z (또는 --zero) 옵션을 사용하여 NUL로 구분 (줄 바꿈으로 구분 대신) ) 출력.

Answer

BASH 명령 만 사용하면됩니다 (외부 도구없이).

for file in *; do echo "${file%.*}"; done 

/ usr / bin이없고 파일 이름에 대해 잘 작동 할 때 유용합니다. l ike this.is.image.png 및 모든 확장에 대해.

답변

충분하지 않았나요?

ls -1 | sed "s/\.png//g" 

또는 일반적으로

ls -1 | sed "s/\.[a-z]*//g" 

모든 확장 프로그램을 제거합니다.

댓글

  • 그렇지만 다른 솔루션도 작동합니다.
  • 모든 Unix / Unix Like 시스템에는 필수 유틸리티이므로 sed가 설치되어 있거나 설치되어 있어야합니다. 표준에 따라.
  • 그렇지만 ls는 출력이 터미널이 아닐 때 해당 옵션없이 어쨌든 수행합니다.
  • 경고 ls -1 | sed 's/\.[a-z]*//g'Image.png.jpg.png 키를 항상 잘라내는 파일 이름이있는 경우 실패합니다. (.png). Unix에서는 이상한 파일 이름을 The new art of working on .png?files and other formats.png로 허용합니다. 여기서 ?는 개행 문자입니다. 불행히도 ls 출력을 단순히 파이프 / 파싱하는 모든 솔루션은 문제가 발생합니다. ms는 이러한 사례를 관리합니다 …
  • g 한정자가 있습니까? \.png가 나타날 때마다가 아니라 줄 끝에서만 제거하려고합니다.

답변

ls를 파싱하거나 find [

1 , 2 ]

안전하지 않은 주로 파일 이름 에서 찾을 수 있기 때문에 ls 또는 find의 출력을 구문 분석 (파이핑)합니다. em> 일반적이지 않은 문자를 줄 바꿈 , … 여기에서 순수한 쉘주기가 작동합니다. [ cuonglm ] .
-exec 파이프되지 않은
find 명령도

작동 :

find ./*.png -exec basename {} .png \; 

업데이트 / 메모 : find .를 사용하여 숨겨진 파일도 검색하거나 find ./*.png를 사용할 수 있습니다. 숨겨지지 않은 것만 얻으려면. find *.png -exec ...를 사용하면 .png라는 파일이있는 경우 문제가 발생할 수 있습니다. find는 옵션으로 가져 오기 때문입니다. -maxdepth 0를 추가하여 Dir_01.png 또는 find ./*.png -prune -exec ...라는 이름의 디렉토리로 내려 가지 않도록 할 수 있습니다. maxdepth는 허용되지 않습니다 (Stéphane에게 감사드립니다). 이러한 디렉토리를 나열하지 않으려면 -type f 옵션을 추가해야합니다 (다른 유형의 비정규 파일도 제외됨). 사용 가능한 모든 옵션에 대한보다 완전한 파노라마를 보려면 man를 살펴보고, 더 나은 이식성을 위해 POSIX를 준수하는지 확인해야합니다.

일부 단어 추가

예를 들어 문서에서 제목을 복사하여 파일 이름에 붙여 넣으면 하나 이상의 줄 바꿈이 파일 이름 자체에서 끝날 수 있습니다.개행 바로 앞에 사용해야하는 키도 제목에 포함 할 수있을 정도로 불행 할 수도 있습니다.

The new art of working on .png files and other formats. 

테스트하려면 다음을 수행 할 수 있습니다. 명령을 사용하여 이와 같은 파일 이름을 만듭니다.

touch "A file with two lines"$"\n""and This is the second.png" touch "The new art of working on .png"$"\n""files and other formats.png" 

간단한 /bin/ls *png는 인쇄 할 수없는 문자 대신

A file with two lines?and This is the second.png The new art of working on .png?files and other formats.png 

ls 또는 find의 출력 을 파이프합니다. 다음 명령은 이해할 수있는 힌트가 없습니다. 현재 줄이 새로운 파일 이름 에서 온 것이거나 파일 이름 의 선행에서 줄 바꿈 문자가 뒤에 오는 경우. 실제로 불쾌한 이름이지만 여전히 합법적 인 이름입니다.

쉘 Parameter-Expansion, ${parameter%word}가있는 쉘주기 printf 또는 echo 변형은 [ cuonglm ], [ Anthon1 ] .

for f in *.png; do printf "%s\n" "${f%.png}" ; done 

맨 페이지에서 셸 매개 변수 확장 [ 3 ]

$ {parameter % word}
$ {parameter %% word}

… 확장의 결과는 일치하는 패턴이 가장 짧은 매개 변수 값 ( %대소 문자) 또는 가장 긴 일치 패턴 ( %%대소 문자)이 삭제되었습니다.

댓글

  • 또한 find 명령은 약간의 변수입니다 (예 : files.png라는 디렉토리가있는 경우)
  • @BroSlow에게 위의 답변을 작성할 때 I 그 순간에 존재하는 다른 변종 13 개 (모두)를 시도했습니다. 명령 줄을 통해 스크립트에서 쉘 호출의 인수로 실행되었습니다. 똑같이하고 그들이 당신이 기대하는 방식으로 행동하는지 알려주십시오. bash 4.3.11, 대시 0.5.7-4, zsh (필요한 경우) 5.0.2로 테스트를 수행했습니다. 더 많은 것을 추가하는 이 게시물 을 자유롭게 읽으십시오. find의 출력 파이핑 에 동의합니다. 이에 대해 명백하게 -exec를 제안했습니다. , 제목에 썼습니다. :-).
  • 위키를 다시 읽습니다. 여기에서 논의되는 ‘ ‘이기 때문에 여전히 예제를 파이프해야한다고 생각합니다. 그리고 대부분의 최신 버전의 ls에서는 출력이 파이프되거나 리디렉션 될 때 아무런 문제가 없지만 위키에서 언급했듯이 모두 작동하지 않을 수 있습니다. 대부분은 출력이 터미널로 전송 될 때 특수 문자 대신 ? 만 삽입합니다. 즉, echo *.png | od -cls *.png | od -c를 수행합니다. 줄 바꿈 문제는 ls의 문제가 아니라 ‘ 모든 명령의 문제입니다 ‘ t null은 파이프의 양쪽에서 종료됩니다.
  • printf "${f%.png}\n"는 잘못되었습니다. 첫 번째 인수는 형식입니다. ‘ 거기에서 변수 데이터를 사용해서는 안됩니다. DoS 취약성으로 보일 수도 있습니다 (예를 들어 %1000000000s.png 파일로 시도).
  • 당신 ‘ d find ./*.png -prune -exec...가 필요하거나 ‘ -로 시작하는 파일 이름 (및 유형 디렉토리, -maxdepth는 이식 가능하지 않음)

답변

사용 rev :

ls -1 | rev | cut -f 2- -d "." | rev 

rev는 모든 문자열 (줄); 첫 번째 “.”다음에 모든 것을 잘라냅니다. rev는 나머지를 되돌립니다.

grep “alma”를 원하는 경우 :

ls -1 | rev | cut -f 2- -d "." | rev | grep "alma" 

댓글

  • 여기서 기본값 인 -1는 필요하지 않습니다.
  • 이것은 My.2016.Summer.Vacation.png
  • @DavidConrad라는 파일에서 심하게 실패합니다. 내 잘못 : / cut -f 2- li로 수정했습니다. >
  • 이제 해당 파일과 함께 작동하지만 .png가있는 파일과 바로 뒤에 개행 문자가있는 파일에서는 작동하지 않습니다. 놀라움을 잘 숨기는 것을 좋아하기 때문에 … 🙂

답변

디렉토리에 확장자가 .png 인 파일 만 있다는 것을 알고 있었다면 다음을 실행했을 것입니다. ls | awk -F. "{print $1}"

이것은 다음의 첫 번째 “필드”를 반환합니다. filename.extension이있는 모든 것.

예 :

[rsingh@rule51 TESTDIR]$ ls 10.png 1.png 2.png 3.png 4.png 5.png 6.png 7.png 8.png 9.png [rsingh@rule51 TESTDIR]$ ls | awk -F. "{print $1}" 10 1 2 3 4 5 6 7 8 9 

댓글

  • 안타깝게도 모두 실패합니다. 둘 이상의 .가있는 파일 이름 , Image.1.png 좋지 않은 파일에도 이름 , 안에 특수 문자가 있습니다. 줄 바꿈 또는 awk, RS에서 (입력) 레코드 구분자로 사용할 줄입니다. ls 출력은 예상하지 못할 때 발생할 문제를 숨기는 것을 좋아하므로 파싱하지 않는 것이 좋습니다. 해당 참조 1 또는 2 에서 자세한 내용을 확인할 수 있습니다. BTW awk를 사용하는 것이 좋습니다. 한 가지 대답에 몇 가지 예를 넣었습니다.
  • 사실, Colin이 제공 한 샘플을 고려하면 잘 작동합니다. 귀하가 제안한 사례에서 작동하도록하기 위해 ‘ 다음으로 변경하겠습니다. [rsingh @ rule51 TESTDIR] $ ls | sed -e ‘ s / .png $ // ‘ 10 1 2 3 4 5 6 7 8 9 harry.the.bunny 뭐죠 .a.png.filename 어렵지 않지만 Colin ‘의 필요를 감안할 때 ‘ 문제가 무엇인지 잘 모르겠습니다. ls를 구문 분석하고 있습니다.
  • 죄송합니다 … ‘ iv id =의 출력을 수정하기 전에 ‘ 파일이있는 디렉토리를 표시하지 않았다는 것을 깨달았습니다. “cb80420c6c”>

ls ‘ [rsingh @ rule51 TESTDIR] $ ls 10.png 2.png 4.png 6.png 8.png harry.the.bunny. png 1.png 3.png 5.png 7.png 9.png whats.a.png.filename.png [rsingh @ rule51 TESTDIR] $ ls | sed -e ‘ s / .png $ // ‘ 10 1 2 3 4 5 6 7 8 9 harry.the.bunny 뭐죠 .a.png.filename

  • note1 \. div에서 .를 이스케이프해야합니다. > sed -e 's/\.png$//' 안에 있지만 방금 작성된 답변이됩니다. 🙁 note2 당신은 ls | awk -F. '{if ($NF=="png") {for (i=1;i<NF-1;i++) printf("%s.", $i) ; printf $(NF-1)"\n"}}'와 같이 awk를 사용할 수 있습니다 … 항상 awk가 줄이 도착하는지 알 수없는 문제는 파일 이름 안에 줄 바꿈이 있는지 여부를 알 수 없습니다. 나는 내 대답에서 더 잘 말하려고 노력했습니다.
  • Hastur에게 감사합니다. 또한이 경우에는 sed 대신 awk를 사용하지 않았습니다.
  • Answer

    “확장자없이 모든 이름이 나열된 텍스트 파일이 있습니다. 텍스트 파일을 폴더와 비교하여 어떤 파일이 누락되었는지 확인하는 PHP 스크립트를 만들고 싶습니다.”:

    for file in $(cat yourlist) ; do [ -f "${file}.png" ] || { echo "$file : listed in yourlist, but missing in the directory" } done #assumes that filenames have no space... # otherwise use instead: # while IFS= read file ; do ...(same inner loop as above)... ; done < yourlist 

    및 그 반대 :

    for file in *.png ; do grep "^${file%.png}$" yourlist >/dev/null || { echo "$file: present in the directory but not listed in yourlist" } done #I assume there are no spaces/tabs/? before/after names in "yourlist". Change the script accordingly if there are some (or sanitize the list) 

    답변

    ls -l | sed "s/\.png$//"

    @roaima가 강조한 가장 정확한 방법입니다. 이스케이프 된 \.png 파일이 없으면 a_png.png라는 파일은 다음과 같이 나열됩니다. a_

    댓글

    • ls -l를 사용하면 OP에서 요청한 내용이 아닌 파일 세부 정보를 제공합니다. about.

    답변

    간단한 셸 라인 (대시가 아닌 ksh, bash 또는 zsh) :

    set -- *.png; printf "%s\n" "${@%.png}" 

    단순 함수 (확장자 없음) :

    ne(){ set -- *.png; printf "%s\n" "${@%.png}"; } 

    또는 제거하는 함수 지정된 모든 확장자 (기본적으로 png) :

    ne(){ ext=${1:-png}; set -- *."$ext"; printf "%s\n" "${@%.${ext}}"; } 

    다음으로 사용 :

    ne jpg 

    출력이 별표 *이면 해당 확장자를 가진 파일이없는 것입니다.

    답변

    다음 피드를 시도해 볼 수 있습니다. ls의 출력은 “.”입니다. 모든 파일에 name.png가 있으므로 첫 번째 열을 인쇄합니다.
    ls | awk -F"." "{print $1}"

    Answer

    sed에 액세스 한 경우 파일 확장자 (png, jpg, tiff 등)에 관계없이 마지막 파일 확장자를 제거하므로 더 좋습니다.

    ls | sed -e "s/\..*$//" 

    댓글

    • this.is.a.dotty.txt와 같은 파일 이름에 대한 중단. 대신 s/\.[^.]*$//를 사용해보세요.

    답글 남기기

    이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다