목록을 읽을 때 파일 이름에서 지정된 용어를 제거하는 방법은 무엇입니까?

목록을 읽을 때 파일 이름에서 지정된 용어를 제거하는 방법은 무엇입니까?

저는 개인 프로젝트의 이 단계를 시작하고 있습니다. 삭제하고 싶은 "1980p", "webrip" 등과 같은 용어가 가득한 비디오 파일 모음이 많이 있습니다.

명령줄에서 Perl 이름 바꾸기를 사용하는 것은 충분히 간단하거나 GUI에서 이름 바꾸기를 사용하여 수행할 수 있지만 단점은 디렉토리를 변경하거나 새 세션을 시작할 때마다 동일한 정보를 계속해서 입력하게 된다는 것입니다. 다시.

첫째, 저는 zsh를 사용하고 있습니다. 둘째 - 파일/폴더 이름에 공백이 없도록 점, 공백, 대시 등을 밑줄로 성공적으로 변환할 수 있습니다.

세 번째 - 작업을 단순화하기 위해 모든 파일/폴더 이름을 소문자로 변환했습니다.

넷째 - 내가 뭔가 잘못하고 있거나 쉘의 재귀가 히트하거나 누락될 수 있으므로 폴더별로 수행하겠습니다.

use strict;
use warnings;

while read i
do
my $i=$(echo $i)
find . -iname "*$i*" rename 's/"$i"//' {} \;
done < /home/terry/.local/bin/Persistent_File_Renamer/persistent_data.txt

"전역" 경고를 보내주세요.

이것을 찾았지만 터미널이 닫힙니다.

if [ $# != 1 ]; then
    echo "Usage: $0 input-file"
    exit 1
else
    infile=$1
fi

exec 3< /home/terry/.local/bin/Persistent_File_Renamer/persistent_data.txt

until [ $done ]
do
    read <&3 myline
    if [ $? != 0 ]; then
        done=1
        continue
    fi
    # process file data line-by-line
    # in here ...
    rename 's/"$myline"//' ./"*$myline*"
done

echo "The End"

나는 멍청한 놈은 아니지만 여기서 어찌할 바를 모르겠습니다. 재사용 가능하고 편집 가능하며 끝이 끝나는 목록으로 끝나는 한 나는 접근 방식을 선호하지 않습니다.

감사해요.

답변1

Perl을 사용할 수 있다면 zshPerl이 필요하지 않습니다 rename. 똑같이 강력하고 더 안정적 zsh입니다 .zmv

autoload -Uz zmv
strings_to_remove=(
  ${(f)"$(<~/.local/bin/Persistent_File_Renamer/persistent_data.txt)"}
) &&
  zmv -n '(**/)(*)' '$1${${(L)2//[. _-]##/_}//(${(~j[|])strings_to_remove})}'

어디:

  • ${(f)"$(<file)"}줄 바꿈으로 파일 내용을 분할하고 여기에서 배열에 할당된 빈 줄을 삭제합니다.
  • zmv패턴과 일치하는 모든 파일 (**/)(*)(모든 수준의 숨김이 아닌 디렉터리에 있는 숨김이 아닌 파일)의 이름을 두 번째 인수의 코드 확장(깊이 우선)으로 바꿉니다.
  • ${(L)2}$2(여기서 캡처된 파일의 기본 이름)을 소문자로 변환합니다.
  • ${var//[. _-]##/_}_하나 이상의 .공백 -문자 시퀀스를 1 로 바꿉니다 _.
  • ${(~j[|])array} joins 배열의 요소이지만 |with는 리터럴이 아닌 와일드카드 연산자로 처리 ~됩니다 .||

만족스러우면 삭제 -n(테스트 실행)합니다.

strings_to_remove=(worst bad)모든 문자열을 한번에 교체하기 때문에 이라는 파일명이 있으면 wobadrst.txt으로 교체되며 worst_txt, worst삭제되지 않으니 주의하세요. 귀하의 방법에서도 마찬가지입니다.

을 사용하여 renameperl에서 File::RenameUTF-8로 인코딩된 파일 이름을 가정하면 다음과 같은 작업을 수행할 수 있습니다.

find . -depth ! -name . -print0 |
  LIST=~/.local/bin/Persistent_File_Renamer/persistent_data.txt \
  PERL_UNICODE=S rename -n -0 -d '
    use vars qw($pattern);
    BEGIN {
      open LIST, "<", $ENV{LIST} or die "$ENV{LIST}: $!\n";
      chomp(my @strings_to_remove = grep {!/^$/} <LIST>);
      our $pattern = join "|", map {qr{\Q$_\E}} @strings_to_remove;
    }
    s/[_ .-]+/_/g;
    $_ = lc $_;
    s/$pattern//g'

그럼에도 불구하고 쉘 변수의 확장을 Perl 코드에 포함시키고 싶지는 않을 것입니다. 이는 명령 주입 취약점이 될 수 있기 때문입니다. $ENV{LIST}여기에서 파일에 대해 했던 것처럼 환경을 통해 Perl 스크립트에 데이터를 전달할 수 있습니다 .

관련 정보