파일 이름을 읽어 파일을 다른 디렉터리로 이동합니다.

파일 이름을 읽어 파일을 다른 디렉터리로 이동합니다.

파일 이름을 읽어서 파일을 이동해야 합니다. 시스템 생성 파일을 이동해야 하는데 이름에 타임스탬프가 포함되어 있습니다. 월별로 파일명을 읽어서 파일을 이동해야 합니다.

파일 이름에 가 포함되어 있으면 디렉터리 201601*.txt로 이동합니다 2016/January. 파일 이름에 다음이 포함되어 있으면 디렉토리 등 201602*.txt으로 이동하십시오 .2016/February

답변1

날짜 문자열이 파일 이름에 있고 모든 파일이 동일한 디렉터리에 있으면 다음을 수행할 수 있습니다.

mv 201601*.txt 2016/January

이 작업을 수동으로 12번 수행하는 것은 번거로울 수 있으므로 숫자와 해당 월 이름이 포함된 목록을 생성하겠습니다.

$ paste <(printf '%s\n' {01..12}) <(cal 2016 | grep -Po '\s+\K[A-Z]\w{2,}') 
01  January
02  February
03  March
04  April
05  May
06  June
07  July
08  August
09  September
10  October
11  November
12  December

그런 다음 이를 구문 분석하여 mv명령을 빌드합니다.

$ paste <(printf '%s\n' {01..12}) <(cal 2016 | grep -Po '\s+\K[A-Z]\w{2,}') | 
    while read num month; do echo mv "*2016$num*" 2016/"$month"; done
mv *201601* 2016/January
mv *201602* 2016/February
mv *201603* 2016/March
mv *201604* 2016/April
mv *201605* 2016/May
mv *201606* 2016/June
mv *201607* 2016/July
mv *201608* 2016/August
mv *201609* 2016/September
mv *201610* 2016/October
mv *201611* 2016/November
mv *201612* 2016/December

요구 사항이 충족된다고 확신하면 삭제하여 echo실제로 파일을 이동하세요.

paste <(printf '%s\n' {01..12}) <(cal 2016 | grep -Po '\s+\K[A-Z]\w{2,}') | 
    while read num month; do echo mv "*2016$num*" 2016/"$month"; done

설명하다

Perl 호환 정규 표현식( )을 사용하여 실행 grep -Po '\s+\K[A-Z]\w{2,}')하고 각 줄의 일치하는 부분만 인쇄합니다( ). 사용된 정규식은 하나 이상의 공백 문자( ), 그 뒤에 대문자( ) 및 2개 이상의 단어 문자( )를 찾습니다. "이 이전의 모든 내용을 무시합니다"를 의미하며, 이는 명령이 일치하는 문자열 부분만 인쇄하도록 합니다.grep-P-o\s+[A-Z]\w{2,}\K뒤쪽에공백. 전체 프로세스에서는 월 목록만 인쇄합니다.

답변2

지쉬이름 패턴을 기반으로 파일 이름을 바꾸는 좋은 기능이 있습니다.zmv. 대체 모드에서는 $f원래 이름 전체가 지정됩니다 $1. $2등은 괄호 안의 그룹입니다. 월 이름을 저장하려면 배열을 사용하세요.

autoload -U zmv
months=(January February March April May June July August September October November December)
zmv '(2016)(<1-12>)*.txt' '$1/$months[$2]/$f'

여기의 패턴은 간단하기 때문에 루프를 사용하여 bash 및 ksh에 적용하는 것은 그리 어렵지 않습니다. 몇 가지 사항에 주의해야 합니다. 월 번호에서 앞에 오는 0을 제거하면 배열 인덱스가 0에서 시작하는 것으로 해석되지 않습니다.

months=(January February March April May June July August September October November December)
for f in 2016[0-9][0-9]*; do
  y=${f:0:4} m=${f:4:2}
  mv -- "$f" "$y/${months[${m#0}]}/$f"
done

또 다른 접근 방식은 Perl 이름 바꾸기 스크립트(또는데비안 버전또는유니코드::배틀 버전).

rename 'BEGIN {@months = qw(January February March April May June July August September October November December)}
        s!^([0-9]{4})([0-9]{2})!$1/$months[$2]/&!' 2016[0-9][0-9]*

답변3

다음은 bash파일을 반복하여 구성 요소와 일치하는 파일을 이동하는 솔루션입니다( yyyymm2000-2099 범위의 값에 대해).yyyy

months=('' January February March April May June July August September October November December)

for f in 20[0-9][0-9][0-3][0-9]*
do
    year=$(echo "$f" | grep -Po '^20\d\d')           # Extract the four digit year, 20nn
    mm=$(echo "$f" | grep -Po '^(?<=20\d\d)\d\d')    # Find the two digit month number 01-12
    month=${months[$mm]}                             # Convert to a month name

    test -n "$year" -a -n "$month" && echo mv "$f" "$yyyy/$month/$f"
done

실행할 준비가 되면 echo접두사를 제거하세요.mv


모든 파일이 다음으로 시작한다는 것을 알고 있다면 2016이는 약간 단순화될 수 있습니다 .

for f in 2016[0-3][0-9]*
do
    mm=$(echo "$f" | grep -Po '^(?<=2016)\d\d')    # Find the two digit month number 01-12
    month=${months[$mm]}                           # Convert to a month name

    test -n "$month" && echo mv "$f" "2016/$month/$f"
done

관련 정보