다음과 같은 디렉토리에 있는 파일의 이름을 바꿔야 합니다.
11-Vnnn_S2_L001_aaa_bbb_ccc_ddd.ext
도착하다
Vnnn.ext
basename
Linux에서 명령을 사용하여 이를 수행할 수 있는 방법이 있습니까 ?
저는 코딩을 처음 접했기 때문에 몇 가지 설명을 기꺼이 제공해 드리겠습니다.
답변1
간단한 루프:
for name in *.ext; do
newname=${name%%_*}.ext
newname=${newname#*-}
echo mv -- "$name" "$newname"
done
이는 .ext
현재 디렉토리에서 끝나는 모든 이름을 통해 반복됩니다(따라서 먼저 해당 디렉토리로 변경하십시오). 이러한 각 이름에 대해 변수는 먼저 이름의 newname
첫 번째 문자 앞 부분에 설정되고 끝에 추가됩니다. 그런 다음 첫 번째 문자 앞의 값을 삭제하여 최종 값을 만듭니다 ._
.ext
-
newname
여기에 사용된 두 인수는 각각 값의 끝에서 가장 긴 일치 하위 문자열과 처음부터 가장 짧은 일치 하위 문자열 바꾸기 ${variable%%pattern}
및 제거입니다.${variable#pattern}
pattern
$variable
명령 을 실행하여 echo
제대로 작동하는지 확인한 다음 echo
이전 mv
내용을 삭제하여 실제로 파일 이름을 바꾸십시오.
답변2
다음을 사용해 볼 수 있습니다 rename
.
rename 's/^[^-]+-([^_]+).+(\.[^.]+)$/$1$2/' *.ext
-
첫 번째와 첫 번째 사이의 부분이 추출되고 _
확장자가 추가됩니다. 먼저 사용해보시고 rename -n '...'
만족스러우면 삭제하세요 -n
.
이 구문은 캡처 그룹을 사용하여 원본 파일 이름을 다음으로 나눕니다.
- 처음부터 처음까지의
-
모든 것 :^[^-]+-
, 즉 하나 이상의 문자로 시작하는 문자열아니요-
, 그 다음에 하나의-
. _
그 이후의 모든 내용을 포함하는 "캡처 그룹"(첫 번째 : 까지 포함) , 즉 그렇지 않은 하나 이상의 문자 - 실제 값은 나중에([^_]+)
대체 텍스트에서_
참조될 수 있습니다.$1
- 그 이후의 모든 것(포함하지 않음)마지막
.
:.+
실제로는 "모든 종류의 하나 이상의 문자"를 의미합니다..
"끝까지"의 의미는 정의의 마지막 부분에서 나옵니다. .
문자열 끝까지 마지막 항목과 그 이후의 모든 항목을 포함하는 "캡처 그룹" :(\.[^.]+)$
- 이 공식은 캡처 그룹 콘텐츠가 리터럴로 시작.
하고 다음 문자만 포함하도록 강제합니다.아니요.
, 문자열 끝까지$
; 이것만이 이전 그룹이 마지막 그룹을 제외한 모든 것을 삼키는 것을 보장합니다.
. 마찬가지로 실제 콘텐츠는 나중에 참조될 수 있습니다$2
(정규식의 두 번째 캡처링 그룹이므로).
그러면 대체 텍스트에는 두 캡처 그룹의 실제 콘텐츠만 포함됩니다 $1$2
.
답변3
AdminBees 솔루션과 유사하게 다른 문제에 더 쉽게 적응할 수 있으며 다음과 같은 bash 내장 기능을 사용할 수 있습니다.
for file in *
do
if [[ "$file" =~ ^[^-]*-([^_]+)_.*\.ext$ ]]
then
mv "$file" "${BASH_REMATCH[1]}.ext"
fi
done
그것은 무엇을 하는가:
for
바꾸다 in
공백으로 구분된 항목 목록
목록의 각 항목을 반복하여 설정합니다.바꾸다do
와 사이의 명령을 실행합니다 done
.
방법현재 디렉토리의 모든 파일, 노력하다 echo *
. bash의 이전 명령이 내장된 버전 [[
입니다 .test
문서
이제 이 복잡한 정규식을 풀어보겠습니다.
^
-입력 라인의 시작
이어서 [^-]
-제외한 모든 문자 -
, *
-몇 번이라도 반복하세요, 그 다음에는 -
. 이제 그 사이의 부분이 ()
관심 있는 부분입니다. Bash는 괄호 사이의 일치하는 부분을 배열로 저장합니다.BASH_REMATCH
(관련된). 정규 표현식은 입니다 [^_]+
.제외한 모든 문자 _
,적어도 한 번 이상 반복하십시오., 다음에 _
.
.
-모든 문자, *
여러 번 반복됨*, 그 뒤에 \.
텍스트 가 옵니다 .
(참조여기), ext
그리고 $
,입력 끝(라인).
입력이 파일 이름이므로 -
과 사이의 첫 번째 부분을 추출하여 _
에 저장합니다 ${BASH_REMATCH[1]}
. 입력 파일 이름이 해당 패턴과 일치하면 일반 이전 mv
이름 바꾸기를 사용하여 파일 이름 $file
에 our_matched_part.ext
공백이 없으면 따옴표가 엄격하게 적용되지 않습니다. 필요하지만 이는 좋은 습관입니다.
도움이 되었기를 바랍니다!
편집자: 아, 젠장. AdminBee가 게시물을 편집했는데 나는 그것을 보지 못했습니다. 아 글쎄...
*-something_*.ext
EDIT2: 더 많은 리터럴 부분(예: 숫자)을 추가하여 모든 파일이 아닌 특정 파일의 이름만 바꾸도록 정규 표현식을 추가로 제한할 수 있습니다 [0-9]+
.
답변4
ls 11-Vnnn_S2_L001_aaa_bbb_ccc_ddd.ext| awk -F "[-_]" '{print "mv " $0" " $2".ext"}' |sh
테스트를 거쳐 잘 작동함