내 유닉스 디렉토리에는 다음과 같은 파일이 많이 있습니다.
filename_1234567.txt
다음과 같이 파일 이름 앞에 마지막 세 문자를 복사하여 각 파일 이름을 바꿔야 합니다.
567_filename_1234567.txt
참고: 확장자와 파일 이름은 모두 가변적입니다.
저는 솔라리스 머신에서 실행하고 있습니다.
답변1
그리고 zsh
:
autoload zmv
zmv -n '*(???).*' '$1_$f'
만족스러우면 삭제하세요 -n
.
답변2
파일 이름 앞에 밑줄이 오는 파일 기본 이름의 마지막 세 문자를 추가하시겠습니까?
#!/bin/bash
EXT=.txt
for file in *${EXT}; do # presuming all the filenames have no spaces
base=${file%${EXT}}
prefix=${base:(-3)}
newname=${prefix}_${base}${EXT}
mv ${file} ${newname}
done
Korn 쉘에서는 사용하는 트릭이 bash
구체적이기 때문에 작동하지 않습니다.
ksh[3]: prefix=${base:(-3)}: bad substitution
답변3
나는 다음과 같은 일을 좋아합니다:
#!/bin/sh
for i in filename_*.txt; do echo "$i"; done |
sed "s/filename_\([0-9]*\)\([0-9]\{3\}\)\.txt/mv -i 'filename_\1\2.txt' '\2_filename_\1\2.txt'/g"
mv
그러면 작업을 완료한 명령 목록이 인쇄됩니다. 올바른 명령이 출력되면 | sh
sed 명령 끝에 추가하여 쉘이 해당 명령을 실행하도록 하세요.
스크립트는 sed
submit 명령 s
과 역참조 기능을 사용하여 정규식과 일치하는 문자열 부분을 바꿉니다.
s/regex/replacement/
\(
내부와 사이의 정규식 패턴 부분은 \)
대체 문자열에서 인용될 수 있습니다. \N
여기서 in은 숫자입니다.
답변4
순수한 awk
솔루션: 기본 아이디어는 기본 이름의 마지막 3자를 추출하는 것입니다. 이는 하위 문자열 형식 length - 6
( .txt
확장자를 고려해야 하기 때문에 6자)을 의미합니다 length - 3
. 여기서는 먼저 해당 하위 문자열을 VAR로 추출한 mv
다음 실행할 두 개의 파일 이름이 포함된 명령; 마지막으로 system
함수에 명령을 실행하도록 요청합니다.
암호:
awk 'BEGIN{
VAR=sprintf("%s",substr(ARGV[1],length(ARGV[1])-6,3));
CMD=("mv "ARGV[1]" "VAR"_"ARGV[1]);
print CMD;
system(CMD);
close(CMD)
}' filename_1234567.txt
데모:
$ awk 'BEGIN{VAR=sprintf("%s",substr(ARGV[1],length(ARGV[1])-6,3)); CMD=("mv "ARGV[1]" "VAR"_"ARGV[1]); print CMD; system(CMD); close(CMD)}' filename_1234567.txt
mv filename_1234567.txt 567_filename_1234567.txt
$ ls filename_1234567.txt
ls: cannot access filename_1234567.txt: No such file or directory
$ ls 567_filename_1234567.txt
567_filename_1234567.txt
$