다음과 같은이 게시물참고로 오류 없이 find
and 명령을 실행할 수 있지만 파일 이름은 동일하게 유지됩니다.sed
옷을 벗으려고 노력 중발음 _de_현재 디렉토리의 모든 mp3:
pronunciation_de_wählen.mp3
pronunciation_de_wange.mp3
pronunciation_de_weil.mp3
pronunciation_de_werden.mp3
pronunciation_de_zentrum.mp3
명령 문제를 해결하기 전에 빠른 상태 확인:
find . -name "*.mp3"
현재 디렉터리의 모든 mp3를 반환합니다. 이제 이 부분이 작동한다는 것을 알았으니 계속하세요...
sed --version
반품sed (GNU sed) 4.4
난 달린다find . -name "*.mp3" -exec sed -i 's/pronunciation_de_//g' {} \;
무슨 일이 일어나고 있는지 완전히 이해했는지 확인하려면 다음을 수행하세요.
find .
달리다찾다현재 디렉터리의 명령입니다.
-name "*.mp3"
모든 .mp3 파일 형식을 반환합니다.
-exec
입력한 다음 명령을 실행합니다.
sed -i
이것-나전환이란 (임시) 복사본이 아닌 실제 파일에서 작업하는 것을 의미합니다.
을 위한 's/old_word/new_word/g'
:
- 이것에스sed를 대체 모드로 설정합니다.
- /오래된 단어바꾸려는 단어입니다.
- /새 단어바꾸려는 단어입니다. 내 예에서는 비어 있습니다.
- /G첫 번째 일치 항목뿐만 아니라 모든 일치 항목에 대체를 적용합니다.
{}
이 문자열은 각 반복 중에 파일 이름으로 대체됩니다.
\;
세미콜론 종료됨찾다주문하다. 백슬래시는 세미콜론 문자를 이스케이프하여 쉘이 문자 그대로 해석하는 것을 방지합니다.
나는 이 정보의 대부분을 임의의 블로그와 Stack Exchange 게시물에서 얻습니다.
-exec 옵션 이해find
find의 -exec 명령에서 {} +는 무엇을 의미하나요?
거의 확실히 중복되는 이 질문을 게시하기 전에 시간을 내어 실험하고 조사하고 싶지만 완전히 막혔습니다!
답변1
find -exec ...
한 줄짜리 쉘 스크립트를 사용하여 교체를 수행 할 수 있습니다 .
find . -name "*.mp3" -type f -exec bash -c 'mv "$1" "${1/pronunciation_de_}"' bash {} \;
파일 이름은 실행 중인 bash 프로세스에 {}
매개변수로 전달되며 , bash의 매개변수 확장 기능이 사용되며, in이 처음 나타나는 경우 빈 문자열로 대체됩니다 .$1
${1/pronunciation_de_}
pronunciation_de_
$1
추가 옵션을 사용하면 -type f
일반 파일만 일치하는지 확인할 수 있습니다.
답변2
pronunciation_de_
이름이 로 끝나는 모든 파일에서 접두사를 제거 하려면 .mp3
이름이 일치하는 파일을 검색하여 pronunciation_de_*.mp3
실수로 다른 파일 이름을 수정하지 않도록 해야 합니다(이런 일이 일어날 가능성은 낮음).
줄 중심 텍스트 편집 도구(예: sed
파일 이름)를 사용하지 마십시오. 쉘은 파일 이름에서 접두사 및 접미사 문자열을 효율적으로 제거하는 방법을 알고 있습니다.
다음을 사용하여 find
문제를 해결할 수 있습니다.
find . -type f -name 'pronunciation_de_*.mp3' -exec sh -c '
for pathname do
newname=${pathname##*/} # removes directory path, leaves filename
newname=${newname#pronunciation_de_} # deletes the prefix string
mv -i "$pathname" "${pathname%/*}/$newname"
done' sh {} +
이 명령은 전달 및 테스트된 파일 find
의 경로 이름을 생성 하고 이러한 파일을 일괄적으로 짧은 인라인 스크립트에 공급합니다.-type
-name
sh -c
이 스크립트는 주어진 경로 이름을 반복하고 각 경로 이름에 대한 새 이름을 만듭니다.
- 초기 디렉토리 경로를 제거하고 경로 이름을 다음
./some/path/pronunciation_de_werden.mp3
으로 변경하십시오.pronunciation_de_werden.mp3
- 접두사 문자열을 제거
pronunciation_de_
하고pronunciation_de_werden.mp3
가 됩니다werden.mp3
.
이 명령은 원본 mv
파일을 원본 디렉터리의 새 이름으로 이동하여 원본 파일 ( ${pathname%/*}
원래 경로 이름으로 확장될 디렉터리 경로)의 이름을 바꿉니다.
답변3
당신의:
find . -name "*.mp3" -exec sed -i 's/pronunciation_de_//g' {} \;
파일 찾기(다음을 포함한 모든 유형정기적인,목차,심볼릭 링크,선입선출...), 이름은 현재 작업 이하로 끝나며 .mp3
, 각 파일은 프로그램과 발견된 파일을 작업할 파일로 사용하여 sed
내부 모드에서 실행됩니다 .s/pronunciation_de_//g
그러나 sed
그것은 s
스트림 ed
itor입니다. 그 임무는 텍스트 스트림을 편집하는 것입니다. 파일을 인수로 주면개울~이다콘텐츠파일 이름(이름이 아님)으로 sed
파일 이름이 바뀌지는 않습니다. 파일 이름을 바꾸기 위한 표준 명령은 입니다 mv
. 여기에는 특히 일괄 이름 바꾸기를 위한 일부 명령이 포함될 수 있습니다(파일을 찾고 이름을 편집하는 기능이 내장되어 있을 수도 있음). mmv
, rename
, zmv
.
sed
해당 이름을 스트림으로 제공하면 이를 사용하여 파일 이름을 편집할 수 있지만 이는 매우 번거롭고 안정적으로 수행하기 어려울 수 있습니다 .
LC_ALL=C find . -depth -name 'pronunciation_de_*.mp3' -exec sh -c '
ret=0
for file do
new_file=$(
printf '%s\n' "$file" |
sed "
:1
\$!{
N
b1
}
s|/pronunciation_de_\([^/]*\)\$|/\1|
"
)
mv -i -- "$file" "$newfile" || ret=$?
done
exit "$ret"' sh {} +
(테스트되지 않음)
다음 사항이 어떻게 필요한지 참고하세요.
LC_ALL=C
파일 이름이 로케일의 문자 인코딩으로 인코딩되지 않는 문제를 방지합니다.-depth
나뭇잎을 다루기 전에 가지를 처리하십시오.sed
파이프( )를 통해|
파일 경로를 제공 하고 다른 파이프( )를 통해 출력을 쉘 변수로 수집 할 수 있도록 셸을 실행합니다$(...)
.- 한 번에 한 라인만 처리 하고
sed
파일 경로는 여러 라인으로 구성될 수 있으므로sed
교체를 수행하기 전에 패턴 공간에 모든 라인을 누적하도록 지시해야 합니다. - 파일의 기본 이름만 바뀌고 이전 경로 구성 요소는 바뀌지 않습니다.
-i
이 옵션을 통해 사용자에게 데이터 손실을 방지할 수 있는 기회를 제공하십시오 . 그러나 이름이 지정된 파일./pronunciation_de_weil.mp3
과 이름이 지정된 디렉토리가 있으면 여전히 도움이 되지 않습니다../weil.mp3
이 경우 파일 이름은 자동으로 변경됩니다./weil.mp3/pronunciation_de_weil.mp3
. GNU 구현에는 이러한 상황을 완화할 수 있는 옵션이mv
있습니다 .-T
zmv
(쉘의 자동 로딩 기능)과 비교 zsh
:
autoload zmv
zmv '(**/)pronunciation_de_(*.mp3)' '$1$2'
여기에는 또 다른 이점이 있습니다.
- 실행하기 전에 잠재적인 충돌을 확인하세요.어느이름 바꾸기
- 숨겨진 파일을 건너뜁니다(숨겨진 파일의 이름도 바꾸려는 경우 이를 변경할 수 있습니다
zmv '(**/)pronunciation_de_(*.mp3)(#qD)' '$1$2'
).
1 sed
구현이 이 비표준 확장을 지원하고 다음 매개변수가 백업 접미어로 간주되지 않는다고 가정합니다.
답변4
일괄 작업의 경우 GNU Parallel을 선호합니다.
ls -1 *.mp3 |
sed 's/pronunciation_de_//' |
parallel mv pronunciation_de_{} {}
sed
파일 이름에서 콘텐츠를 제거했습니다 pronunciation_de_
. 그러면 , , ... {}
처럼 될 것입니다.wählen.mp3
wange.mp3