Bash로 일괄 이름 바꾸기 파일
Bash는 버전 번호를 제거하기 위해 일련의 패키지 이름을 어떻게 바꿀 수 있습니까? 나는 모두 주위 놀겠다는 거 봤는데 expr
와 %%
아무 소용.
예 :
Xft2-2.1.13.pkg
된다 Xft2.pkg
jasper-1.900.1.pkg
된다 jasper.pkg
xorg-libXrandr-1.2.3.pkg
된다 xorg-libXrandr.pkg
bash의 매개 변수 확장 기능을 사용할 수 있습니다.
for i in ./*.pkg ; do mv "$i" "${i/-[0-9.]*.pkg/.pkg}" ; done
공백이있는 파일 이름에는 따옴표가 필요합니다.
모든 파일이 동일한 디렉토리에 있으면 시퀀스
ls |
sed -n 's/\(.*\)\(-[0-9.]*\.pkg\)/mv "\1\2" "\1.pkg"/p' |
sh
당신의 일을 할 것입니다. 나오지 명령의 시퀀스를 생성합니다 MV , 명령하는 할 수 있습니다 후 껍질에 파이프. | sh
명령이 원하는 작업을 수행하는지 확인 하려면 먼저 후행없이 파이프 라인을 실행하는 것이 가장 좋습니다 .
여러 디렉토리를 반복하려면 다음과 같이 사용하십시오.
find . -type f |
sed -n 's/\(.*\)\(-[0-9.]*\.pkg\)/mv "\1\2" "\1.pkg"/p' |
sh
에가 있습니다 나오지 순서를 그룹화 정규 표현식은 앞에 백 슬래시 브라켓입니다, \(
그리고 \)
오히려 하나의 브라켓보다, (
하고 )
.
다음과 같이 할 것입니다.
for file in *.pkg ; do
mv $file $(echo $file | rev | cut -f2- -d- | rev).pkg
done
모든 파일이 현재 디렉토리에 있다고 가정합니다. 그렇지 않다면 위에서 Javier가 조언 한대로 find를 사용해보십시오.
편집 : 또한이 버전은 위의 다른 기능과 같이 bash 특정 기능을 사용하지 않으므로 더 많은 이식성을 얻을 수 있습니다.
다음은 현재 허용되는 답변 과 거의 동일한 POSIX 입니다. 이것은 ${variable/substring/replacement}
Bourne 호환 쉘에서 사용할 수 있는 Bash 전용 매개 변수 확장을 교환합니다 .
for i in ./*.pkg; do
mv "$i" "${i%-[0-9.]*.pkg}.pkg"
done
매개 변수 확장 ${variable%pattern}
은 variable
일치하는 접미사가 pattern
제거 된 값을 생성합니다 . ( ${variable#pattern}
접두사 제거 도 있습니다 .)
-[0-9.]*
오해의 소지가 있지만 수락 된 답변에서 하위 패턴 을 유지했습니다 . 정규식이 아니라 glob 패턴입니다. 따라서 "대시 뒤에 0 개 이상의 숫자 또는 점이 표시됨"을 의미하지 않습니다. 대신, "대시, 숫자 또는 점, 그 뒤에 오는 것"을 의미합니다. "anything"은 가장 긴 것이 아니라 가능한 가장 짧은 일치입니다. (배쉬 제공 ##
하고 %%
오히려 짧은보다, 가장 긴 접두사 나 접미사를 트리밍.)
sed
이것에 대해 더 잘 사용하십시오 .
find . -type f -name "*.pkg" |
sed -e 's/((.*)-[0-9.]*\.pkg)/\1 \2.pkg/g' |
while read nameA nameB; do
mv $nameA $nameB;
done
정규 표현식을 파악하는 것은 연습으로 남겨집니다 (공백을 포함하는 파일 이름을 다루는 것처럼)
sed
* nix에서 사용할 수 있다고 가정 할 수 있지만 sed -n
mv 명령 생성을 지원할 수 있을지 확신 할 수 없습니다 . ( 참고 : GNU 만이 작업을 sed
수행합니다.)
그럼에도 불구하고 bash 내장 및 sed, 우리는 이것을 수행하기 위해 쉘 함수를 빠르게 채울 수 있습니다.
sedrename() {
if [ $# -gt 1 ]; then
sed_pattern=$1
shift
for file in $(ls $@); do
mv -v "$file" "$(sed $sed_pattern <<< $file)"
done
else
echo "usage: $0 sed_pattern files..."
fi
}
용법
sedrename 's|\(.*\)\(-[0-9.]*\.pkg\)|\1\2|' *.pkg
before:
./Xft2-2.1.13.pkg
./jasper-1.900.1.pkg
./xorg-libXrandr-1.2.3.pkg
after:
./Xft2.pkg
./jasper.pkg
./xorg-libXrandr.pkg
대상 폴더 만들기 :
mv
은 (는) 대상 폴더를 자동으로 생성하지 않기 때문에 초기 버전의 sedrename
.
상당히 작은 변경이므로 해당 기능을 포함하는 것이 좋습니다.
abspath
bash에는이 빌드가 없기 때문에 유틸리티 함수 (또는 절대 경로)가 필요합니다.
abspath () { case "$1" in
/*)printf "%s\n" "$1";;
*)printf "%s\n" "$PWD/$1";;
esac; }
Once we have that we can generate the target folder(s) for a sed/rename pattern which includes new folder structure.
This will ensure we know the names of our target folders. When we rename we'll need to use it on the target file name.
# generate the rename target
target="$(sed $sed_pattern <<< $file)"
# Use absolute path of the rename target to make target folder structure
mkdir -p "$(dirname $(abspath $target))"
# finally move the file to the target name/folders
mv -v "$file" "$target"
Here's the full folder aware script...
sedrename() {
if [ $# -gt 1 ]; then
sed_pattern=$1
shift
for file in $(ls $@); do
target="$(sed $sed_pattern <<< $file)"
mkdir -p "$(dirname $(abspath $target))"
mv -v "$file" "$target"
done
else
echo "usage: $0 sed_pattern files..."
fi
}
Of course, it still works when we don't have specific target folders too.
If we wanted to put all the songs into a folder, ./Beethoven/
we can do this:
Usage
sedrename 's|Beethoven - |Beethoven/|g' *.mp3
before:
./Beethoven - Fur Elise.mp3
./Beethoven - Moonlight Sonata.mp3
./Beethoven - Ode to Joy.mp3
./Beethoven - Rage Over the Lost Penny.mp3
after:
./Beethoven/Fur Elise.mp3
./Beethoven/Moonlight Sonata.mp3
./Beethoven/Ode to Joy.mp3
./Beethoven/Rage Over the Lost Penny.mp3
Bonus round...
Using this script to move files from folders into a single folder:
Assuming we wanted to gather up all the files matched, and place them in the current folder, we can do it:
sedrename 's|.*/||' **/*.mp3
before:
./Beethoven/Fur Elise.mp3
./Beethoven/Moonlight Sonata.mp3
./Beethoven/Ode to Joy.mp3
./Beethoven/Rage Over the Lost Penny.mp3
after:
./Beethoven/ # (now empty)
./Fur Elise.mp3
./Moonlight Sonata.mp3
./Ode to Joy.mp3
./Rage Over the Lost Penny.mp3
Note on sed regex patterns
Regular sed pattern rules apply in this script, these patterns aren't PCRE (Perl Compatible Regular Expressions). You could have sed extended regular expression syntax, using either sed -r
or sed -E
depending on your platform.
See the POSIX compliant man re_format
for a complete description of sed basic and extended regexp patterns.
I find that rename is a much more straightforward tool to use for this sort of thing. I found it on Homebrew for OSX
For your example I would do:
rename 's/\d*?\.\d*?\.\d*?//' *.pkg
The 's' means substitute. The form is s/searchPattern/replacement/ files_to_apply. You need to use regex for this which takes a little study but it's well worth the effort.
This seems to work assuming that
- everything ends with $pkg
- your version #'s always start with a "-"
strip off the .pkg, then strip off -..
for x in $(ls); do echo $x $(echo $x | sed 's/\.pkg//g' | sed 's/-.*//g').pkg; done
I had multiple *.txt
files to be renamed as .sql
in same folder. below worked for me:
for i in \`ls *.txt | awk -F "." '{print $1}'\` ;do mv $i.txt $i.sql; done
Thank you for this answers. I also had some sort of problem. Moving .nzb.queued files to .nzb files. It had spaces and other cruft in the filenames and this solved my problem:
find . -type f -name "*.nzb.queued" |
sed -ne "s/^\(\(.*\).nzb.queued\)$/mv -v \"\1\" \"\2.nzb\"/p" |
sh
It is based on the answer of Diomidis Spinellis.
The regex creates one group for the whole filename, and one group for the part before .nzb.queued and then creates a shell move command. With the strings quoted. This also avoids creating a loop in shell script because this is already done by sed.
참고URL : https://stackoverflow.com/questions/602706/batch-renaming-files-with-bash
'Programing' 카테고리의 다른 글
JavaScript에서 가능한 {}를 catch하지 않고 {}을 시도 하시겠습니까? (0) | 2020.08.28 |
---|---|
SQL Server 2008 R2에서 CONCAT 함수를 어떻게 사용합니까? (0) | 2020.08.28 |
git-브랜치가 1 커밋만큼 '원산지 / 마스터'보다 앞서 있습니다. (0) | 2020.08.28 |
pom xml의 종속성과 플러그인 태그 간의 Maven의 차이점은 무엇입니까? (0) | 2020.08.28 |
AngularJS-전체 페이지로드로 리디렉션을 수행하려면 어떻게해야합니까? (0) | 2020.08.28 |