bash의 파일 이름 목록에서 파일 이름 확장자를 제거하는 방법

다음으로 생성 한 파일 목록에서 파일 이름 확장자를 제거하려고합니다. bash 스크립트 :

 #!/bin/bash file_list=$(find . -type f) #assuming that the files are stored in the same directory trimmed_file_list=$(printf "%s\n" "${file_list[@]%.*}") printf "%s\n" "${trimmed_file_list[@]}" 

이 확장은 목록의 마지막 항목에서 확장을 잘라내지만 이전 항목은 잘라냅니다.

예를 들어 다음 목록을 원합니다.

 file1.pdf file2.pdf file3.png 

To be

 file1 file2 file3 

하지만 대신 다음과 같이 표시됩니다.

 file1.pdf file2.pdf file3 

루프에서이 작업을 수행하지 않는 것이 좋으며 매개 변수 확장을 사용하고 싶습니다. 파일의 마지막 확장명 만 제거하고 싶기 때문에 잘라내기를 피하고 싶습니다.

매개 변수 확장에 대한 주제가 상당히 많으며 bash가 “의 줄 바꿈 사용 … 확실하지 않습니다. 기존의 다른 주제에서이 문제를 설명한다면 무슨 일이 일어나고 있는지 완전히 이해하지 못합니다.

보이는 주제 관련이 있지만 문제가 해결되지 않는 것 같습니다.

주석

  • 제목에 배열이 언급되어 있지만 코드에 배열이 없습니다.
  • @Kusalananda 감사합니다! 저는 ' 요청한 이후로 그것을 깨달았습니다. 아직 배우는 중 🙂
  • @Kusalananda I ' 문제에 더 가깝게 일치하도록 질문을 수정했습니다. 그러면 잘못된 Google 검색이 페이지에 도달하는 것을 방지 할 수 있습니다. 정보 감사합니다!

답변

모든 작업을 하나의 명령으로 수행 할 수 있습니다.

find /path/to -type f -execdir bash -c "printf "%s\n" "${@%.*}"" bash {} + 

댓글

  • 감사합니다! 실제로 배열의 복사본을 몇 개 만들어야합니다. 하나는 파일 이름이 수정 된 메뉴 용이고 다른 하나는 메뉴에서 파일을 호출 할 수 있도록 원래 인덱스 값을 유지합니다. bash가 얼마나 많은 일을 할 수 있는지 정말 놀랍습니다! 모든 것을 하나의 명령에 포함 할 수있는 능력은 여전히 나를 놀라게합니다! : D

답변

문자열 대신 배열을 만들고 싶을 것 같습니다.

IFS=$"\n" # split on newline only set -o noglob # disable the glob part file_list=($(find . -name "*.*" -type f)) 

또는 bash 4.4 이상에서는 줄 바꿈 문자가있는 파일 경로가 깨지지 않습니다.

readarray -td "" file_list < <(find . -name "*.*" -type f -print0) 

그러면 매개 변수 확장이 작동해야하지만 여기서는 배열 변수를 다시 사용하는 것이 더 합리적입니다.

trimmed_file_list=("${file_list[@]%.*}") 

코드 샘플에서 문자열을 만듭니다. 그런 다음 전체 문자열에서 마지막 점 문자 뒤의 모든 항목을 제거하도록 매개 변수 확장을 요청합니다.

댓글

  • 감사합니다! 아침에 책상에 도착하자마자 테스트하겠습니다.
  • 이것은 해당 디렉토리의 파일 이름에 공백이나 글 로빙 문자가 포함되어 있지 않다고 가정합니다.
  • @Wildcard는 최신 편집에서 해결되었습니다.
  • @Wildcard 포인터 주셔서 감사합니다! 저는 ' 프로그래밍 방식으로이 디렉토리에 드롭되는 파일을 생성하므로 문제가되지 않습니다. '

답변

코드에 배열이 포함되어 있지 않습니다. 또한 $file_list 문자열에 파일 이름 목록을 넣습니다. 문자열의 내용은 file3.png로 끝나고 매개 변수 대체는 문자열에서 .png를 제거하여 단일 파일 이름 문자열을 남깁니다. 마지막 파일 이름에는 파일 이름 접미사가 없습니다.

여러 개의 개별 개체 (경로 이름)를 단일 문자열에 넣으면 이름에 공백 (또는 문자열이 사용하는 구분 기호)이 포함 된 파일에 대해 스크립트가 자동으로 제대로 작동하지 않습니다. 공백으로 find의 출력을 분할하는 것처럼 배열을 사용하면 도움이되지 않습니다.


일반 파일의 모든 파일 이름에서 확장자를 제거하려면 현재 디렉토리 안 또는 아래 :

find . -type f -name "*.*" -exec sh -c " for pathname do printf "Would move %s to %s...\n" "$pathname" "${pathname%.*}" # mv -i "$pathname" "${pathname%.*}" done" sh {} + 

이름에 점이 하나 이상 포함 된 일반 파일을 찾습니다. 이러한 파일의 경로 이름은 파일을 반복하는 작은 셸 스크립트에 일괄 적으로 제공됩니다. 쉘 스크립트는 파일 이름의 마지막 점과 그 뒤에 오는 모든 것을 제거하여 파일 이름을 바꿉니다. 실제 mv 명령은 안전을 위해 주석 처리되어 있습니다.

find 명령은 경로 이름 생성기 역할을합니다. 내부 쉘 스크립트이며 공백, 줄 바꿈 및 탭을 포함하는 경로 이름을 올바르게 처리 할 수 있습니다. 명령의 출력을 변수에 저장할 필요가 없습니다.

경로 이름 배열이있는 경우

shopt -s globstar nullglob file_list=( **/*.* ) # get pathnames of files with dots in their names 

다음으로 접미사없이 경로 이름을 출력 할 수 있습니다.

printf "%s\n" "${file_list[@]%.*}" 

이게 도움이되는지 모르겠습니다. 접미사가없는 경로 이름을 사용 하려는 경우 , 위의 printf 명령의 출력을 사용하는 것은 잘못된 일입니다 (이상한 경로 이름을 다시 처리하지 않는 상태로 돌아올 것입니다). 파일 이름 접미사를 삭제하는 방법은 결과로 수행 할 작업에 따라 다릅니다.

관련 :

의견

  • 감사합니다! bash에 대한 당신의 숙달은 매우 분명합니다! ' 아직 표면을 긁고 있습니다 … 시간을내어 도와 주셔서 감사합니다 🙂

답글 남기기

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