Linux : 파일 이름을 바꾸지 만 확장자를 유지 하시겠습니까? Windows / DOS에서는

Windows / DOS에서는 rename myfile.* yourfile.*이름을 변경하고 확장명을 유지 한다고 말할 수 있습니다. Linux에서 어떻게 달성됩니까?

매뉴얼 페이지는 확장명을 변경하는 방법 만 제안하지만, 내가 원하는 것과 반대입니다.

보너스 :
실제로 사진의 생성 날짜를 파일 이름에 넣고 싶습니다 20091231 2359 New Year.jpg. 나는 그것을 달성하기 위해 사소한 명령 조합이 필요하다고 두려워합니까?



답변

보너스 질문에 대한 답변입니다.

실제로 20091231 2359 New Year.jpg와 같은 것을 얻기 위해 사진의 생성 날짜를 파일 이름에 넣고 싶습니다. 나는 그것을 달성하기 위해 사소한 명령 조합이 필요하다고 두려워합니까?

EXIF 데이터에서 사진의 작성 날짜를 가져 오려는 경우 별도의 도구가 필요합니다. 운 좋게도 옵션을 jhead사용하여 원하는 것을 정확하게 할 수있는 사소한 방법을 제공합니다 -n.

$ jhead -h
 [...]

 -n[format-string]

             Rename files according to date.  Uses exif date if present, file
             date otherwise.  If the optional format-string is not supplied,
             the format is mmdd-hhmmss.  If a format-string is given, it is
             is passed to the 'strftime' function for formatting
             In addition to strftime format codes:
             '%f' as part of the string will include the original file name
             [...]

예를 들면 다음과 같습니다.

$ jhead -n%Y-%m-%d-%f New_year.jpg   
New_year.jpg --> 2009-12-31-New_year.jpg

편집 : 물론, 많은 사진을 위해이 작업을 수행하려면 다음과 같습니다.

$ for i in *jpg; do jhead -n%Y-%m-%d-%f $i; done

날짜 형식을 원하는대로 조정하려면 date --help예를 들어 의 출력을 살펴보십시오 . 사용 가능한 형식 코드가 나열됩니다.

(jhead는 다른 시스템에서 광범위하게 사용할 수 있습니다. 예를 들어 Ubuntu 또는 Debian 인 경우 간단히 입력 sudo apt-get install jhead하여 설치하십시오.)


답변

이름 바꾸기 부분의 경우 ‘이름 바꾸기’프로그램이 작동합니다. 맨 페이지에서 보았던 예와 동일하며 전환했습니다.

justin@eee:/tmp/q$ touch myfile.{a,b,c,d}
justin@eee:/tmp/q$ ls
myfile.a  myfile.b  myfile.c  myfile.d
justin@eee:/tmp/q$ rename -v s/myfile/yourfile/ myfile.*
myfile.a renamed as yourfile.a
myfile.b renamed as yourfile.b
myfile.c renamed as yourfile.c
myfile.d renamed as yourfile.d
justin@eee:/tmp/q$ ls
yourfile.a  yourfile.b  yourfile.c  yourfile.d
justin@eee:/tmp/q$ 


답변

betelgeuse:tmp james$ ls myfile.* yourfile.*
ls: yourfile.*: No such file or directory   
myfile.a    myfile.b
betelgeuse:tmp james$ for file
> in myfile.*
> do
> mv "${file}" "`echo $file | sed 's/myfile\./yourfile./'`"
> done
betelgeuse:tmp james$ ls myfile.* yourfile.*
ls: myfile.*: No such file or directory
yourfile.a  yourfile.b

핵심은 파일 이름의 한 부분을 정규식과 병합하는 방법을 보여주는 예제를 보았을 때 필요한 유일한 예라는 것입니다. 확장자는 유닉스 파일 시스템에서 특별한 상태를 갖지 않습니다-그것들은 .문자 뒤에 나오는 파일 이름의 일부일뿐입니다 .


답변

파일 이름을 조작하는 몇 가지 다른 방법이 있습니다.

for f in *.jpg
do
    mv "$f" "before_part${f%.*}after_part.${f##*.}"
    # OR mv "$f" "before_part$(basename "$f" ".jpg")after_part.jpg"
done

명령 의 매개 변수 확장mv다음과 같이 작동합니다.

${f%.*}-에 포함 된 문자열 끝에서 가장 짧은 일치 패턴을 삭제합니다 $f.이 경우 마지막 점을 포함하여 그 이후의 모든 항목을 삭제하십시오. 단일 %은 “끝에서 가장 짧음”을 의미합니다.

${f##*.}-에 포함 된 문자열의 시작 부분에서 가장 긴 일치 패턴을 삭제합니다 $f.이 경우 마지막 점을 포함한 모든 점 (다른 점도 포함)이 삭제됩니다. 이중 #( ##)은 “처음부터 가장 긴”을 의미합니다.

예를 $f들어 “Foo.bar.baZ.jpg” 가 포함 된 경우 :

echo "${f%.*}"

준다

Foo.bar.baZ

echo "${f##*.}"

준다

jpg

따라서 mv확장 된 명령은 다음과 같습니다.

mv "Foo.bar.baZ.jpg" "before_partFoo.bar.baZafter_part.jpg"


답변

Linux에는 파일 이름 확장자가 없습니다.

정규식을 사용하여 파일 이름에서 특정 하위 문자열을 잘라내어 액세스하십시오.

예:

실제 시나리오 : chm 파일에서 html을 추출하고 있습니다. Windows의 파일 이름은 대소 문자를 구분하지 않으므로 Linux에서는 링크가 끊어집니다. URL에 index.HTML 이라는 파일이 있지만 href = “index.html” 이 있습니다. 따라서 목표는 파일 이름을 링크와 일치하도록 조정하는 것입니다.

변수에 파일 이름이 있다고 가정하십시오.

FILENAME='index.HTML'

버전 3.0부터 bash는 정규 표현식 자체를 지원하므로 문자열 조작을 수행하기 위해 grep / sed / perl 등과 같은 추가 도구가 필요하지 않습니다. 다음 예제는 문자열에서 백엔드 일치를 대체하는 것을 보여줍니다.

echo ${FILENAME/%\.HTML/.html}

원하는 경우 일치 및 대체 문자열을 매개 변수화 할 수 있으며 스크립트 작성시 추가 유연성을 제공합니다. 다음 코드 스 니펫은 동일한 목표를 달성합니다.

match='\.HTML'
replacement='.html'
echo ${FILENAME/%$match/$replacement}

추가 정보는 bash 문서를 참조하십시오.


답변

다른 하나는 다음과 같습니다.

find -name "*.jpg" -printf '"%p" "%h/%TY%Tm%Td %TH%TM %f"\n' | while read -r f
do
    eval "mv ${f}"
done


답변

항상 여러 가지 방법이 있습니다. 다음 스크립트를 / usr / local / bin / mrename으로 설정했습니다.

그런 다음 사진 파일이 포함 된 스크립트에서 다음을 입력하십시오. mrename

스크립트에는 ImageMagick을 사용하여 사진 크기를 조정하는 주석 처리 된 옵션 기능도 있습니다.

이것이 일부 사람들에게 유용하기를 바랍니다.

#!/usr/bin/perl
#
# mrename files
#
#
use strict;

# if no 2 args, use defaults
my $dir = ".";

# read in path from command line
$dir = $ARGV[0] if ( defined( $ARGV[0] ) && $ARGV[0] ne "" );

# read in directory contents
opendir( DIR, $dir );
my @files = readdir( DIR );
closedir( DIR );

# rename and/or scale each file in directory
my $number_of_files = scalar( @files );
my $curfile = 0;

foreach my $file( @files ) {
    # only rename and scale jpg/gif files
    if ( $file =~ /\w+\.(jpg)$/ ) {
        my $extension = $1;
        $extension =~ tr/A-Z/a-z/;
        my $full_filename = "$dir/$file";

        # get stats on file- specifically the last modified time
        (my $dev,my $ino,my $mode,my $nlink,my $uid,my $gid,my $rdev,my $size,
        my $atime,my $mtime,my $ctime,my $blksize,my $blocks) = stat($full_filename);

        # convert last-modified time from seconds to practical datetime terms
        (my $sec,my $min,my $hour,my $mday,my $mon,my $year,my $wday,my $yday,
        my $isdst) = localtime($mtime);

        ++$mon;
        $year += 1900;

        my $filecdate = sprintf( "m%04i%02i%02i_%02i%02i%02i.$extension", $year, $mon, $mday, $hour, $min, $sec );
        my $full_newfilename = "$dir/$filecdate";

        # to scale files, use imagemagick by using the command below instead of mv 
        #my $cmd = "convert $full_filename -resize $scale% $full_newfilename";
        my $cmd = "mv $full_filename $full_newfilename";
        system( $cmd );

        # update percentage done
        my $percent_done = sprintf( "%5.2lf", 100* (++$curfile) / $number_of_files );
        print "\r$percent_done%";
    }
}
print "\n";