Bash 스크립팅을 사용하여 다중 파일 이름 바꾸기


27

Bash 스크립팅을 사용하여 동일한 디렉토리에서 여러 파일의 이름을 바꾸고 싶습니다. 파일 이름은 다음과 같습니다.

file2602201409853.p
file0901201437404.p  
file0901201438761.p  
file1003201410069.p  
file2602201410180.p

다음 형식으로 이름을 바꾸고 싶습니다.

file2503201409853.p
file2503201437404.p  
file2503201438761.p  
file2503201410069.p  
file2503201410180.p

이름 바꾸기 명령에 대해 읽었고 이런 식으로 시도했지만 아무 것도하지 않습니다. 구문에 대한 질문이 있다고 생각합니다. 그런 다음 mv 명령을 사용하여 다음과 같이 루프를 만들 수 있다는 것을 읽었습니다 .

for file in cmpsms*2014*.p; do
    mv "$file" "${file/cmpsms*2014*.p/cmpsms25032014*.p}"
done

그러나 파일 이름을 바꿀 수 없습니다. 내가 무엇을 잘못하고 있지?



2
매개 변수 확장 대체 표현식의 오른쪽에 패턴 표현식을 가질 수 없습니다. 그것이 어디에있을 것으로 기대 했 *습니까?
kojiro

@Kiwy 그 질문은 파일 이름의 일부를 제거하는 것입니다. 어고, 의심 할 여지없이 복제.
CVn

2
다음에는 변경하려는 파일 이름을 설명하십시오 (차이점과 유사점을보기 전에 공정한 부분을 살펴 봐야했습니다). 예제는 좋지만 예제 뿐만 아니라 설명 도 더 좋습니다.
CVn

답변:


42

먼저 이름 바꾸기를 고려하는 것이 옳았습니다. 정규 표현식에 익숙하지 않은 경우 구문이 약간 이상하지만 수행중인 작업을 알고 나면 가장 빠르거나 가장 짧은 경로입니다.

rename 's/\d{4}/2503/' file*

이는 처음 4 개의 숫자와 일치하고 지정한 숫자로 교체합니다.

그리고 테스트 장치는 ( -vn수단 장황하지 않지만 것을) 당신의 파일 이름을 사용 :

$ rename 's/\d{4}/2503/' file* -vn
file0901201437404.p renamed as file2503201437404.p
file0901201438761.p renamed as file2503201438761.p
file1003201410069.p renamed as file2503201410069.p
file2602201409853.p renamed as file2503201409853.p
file2602201410180.p renamed as file2503201410180.p

8
이것은 데비안과 파생어 (Ubuntu, Mint,…)의 Perl 이름입니다. 다른 Linux 배포판에서는 rename완전히 다른 파일 이름 바꾸기 도구 (데비안은로 제공 rename.ul)가 있습니다.
Gilles 'SO- 악마 그만'

이러한 도구가 배포에 부족한 경우 @Michael Campbell의 답변을 참조하십시오. 나는 모든 배포판 rename이 데비안처럼 디폴트를 대체한다고 생각합니다 .
Astery

25

트릭을 수행해야합니다.

for f in file*; do mv $f ${f/${f:4:8}/25032014}; done

4 번째와 12 번째 문자 사이의 문자열을 "25032014"로 바꿉니다.


이것은 for f in file*; do mv $f ${f/${f:4:4}/2503}; done또한 작동합니다.
Avinash Raj

좋습니다. 단어 교체를 위해 정기적 인 단어를 사용하려면 sed처럼 작동합니다. 예 :for f in *Huge*; do mv $f ${f/Huge/Monstrous}; done
Eric

1
@Eric-더 명확하고 우아하다고 생각하기 때문에 대안으로 답변을 게시했습니다. 답변으로 게시하려면 내 것을 삭제합니다. 감사!
Yehosef

큰 따옴표누락 되었습니까?
와일드 카드

"mv : target 'FILE_NAME'은 (는) 디렉토리가 아닙니다"
Aubrey

10

이것은 실제로 @Eric의 답변입니다. 그러나 우아한 답변이므로 더 많은 관심을 끌기 위해 적절한 답변으로 다시 게시하고 있습니다.

for f in *Huge*; do mv $f ${f/Huge/Monstrous}; done

1
ptrn='file[0-9][0-9][0-9][0-9]2014[0-9][0-9][0-9][0-9][0-9].p'
path=/dir
( set -- "${path}/"${ptrn} ; for f ; do {
    echo "mv ${path}/${f} \
        ${path}/file25032014${f#2014}" 
} ; done )

이것은 트릭을해야합니다. 참고-대량 mv 명령을 전달하는 습관은 아닙니다. 기록 된 것처럼 에코입니다. 작동하기 전에 정리해야합니다.


1

디렉토리 탐색을 사용 하여 루핑하지 않고 간단한 기본 방법 :

find -type f | xargs -I {} mv {} {}.txt

모든 파일의 이름이 바뀝니다.

그리고 병렬화 와 함께 작동하는 예제 아래 :

find -name "file*.p" | parallel 'f="{}" ; mv -- {} ${f:0:4}2503${f:8}'

더 나은 솔루션을 상상하는 것은 쉬운 첫 번째 방법이었습니다. 작업 명령을 원할 경우 다음을 수행하십시오.
dtrckd

find -type f -name "file*.p" | parallel 'ext="{}" ; mv -- {} ${ext:0:4}2503${ext:8}'
dtrckd December

0

이런 종류의 일을 많이하면 "rename.pl"을 찾으십시오. 펄 스크립트이지만, 펄 코드 (예 : as /// expression)를 제공하면 해당 표현식이나 코드에 따라 대량으로 이름을 바꿀 수 있습니다.

여기에 기본 버전이 있습니다 : http://stackoverflow.org/wiki/Rename.pl 그러나 인터넷에 떠 다니는 다른 버전이 있습니다. 오랜 세월 동안 주변에있었습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.