파일 이름으로 저장된 날짜를 기준으로 파일 수정 날짜를 설정합니다.

파일 이름으로 저장된 날짜를 기준으로 파일 수정 날짜를 설정합니다.

파일 이름에 파일 생성 날짜( )가 포함된 파일이 많이 있습니다 IMG_YYYYMMDD_hhmmss.jpg.

IMG_20171015_133516.jpg
IMG_20171015_133827.jpg
IMG_20171015_142634.jpg
IMG_20171015_142834.jpg
IMG_20171015_142857.jpg

하지만 실제 파일 생성 날짜는 다릅니다. 파일 이름의 날짜로 다시 설정해야 합니다.

모든 파일의 날짜를 현재 날짜로 변경하는 방법을 알고 있습니다.

find -type f -exec touch {} \;

올바른 형식의 날짜를 얻기 위해 파일 이름을 구문 분석하는 방법touch -t

echo IMG_20171015_133516.jpg | awk -F_ '{print $2 substr($3,0,4) "." substr($3,5,2)}'
201710151335.16

하지만 이러한 명령을 결합하여 모든 파일을 변경하는 방법을 모르겠습니다.

find -type f -exec touch -t"$(echo '{}' | awk -F_ '{print $2 substr($3,0,4) "." substr($3,5,2)}')" {} \;

반품

터치: 잘못된 날짜 형식 "."

답변1

셸에서:

for f in ./IMG_*.jpg ; do 
    t=${f##*/} 
    touch "$f" -t "${t:4:8}${t:13:4}.${t:17:2}"
done

Bash, ksh, zsh 등에는 모두 ${var:n:m}부분 문자열 확장 기능이 있습니다. 재귀적으로 수행해야 하는 경우 활성화 globstar하고 사용하세요 **/IMG_*.jpg.

이를 위해서는 find쉘도 필요합니다:

$ find -name "IMG_*.jpg" -exec bash -c '
  for f; do t=${f##*/}; touch "$f" -t "${t:4:8}${t:13:4}.${t:17:2}" ; done
  ' sh {} \+

스크립트 뒤의 Bash에 대한 첫 번째 인수는 $0일반적으로 쉘 이름이 포함된 변수를 가리킵니다. 나머지는 위치 인수 등으로 이동 $1하거나 $2이를 반복합니다 for f. for f in "$@"여기의 구성은 상당히 일반적입니다(적어도 unix.SE 답변에서는). 이 루프의 주요 부분은 첫 번째 예와 동일합니다.


find질문에 있는 명령은 find .. -exec touch -t"$(...)" {} \;명령 대체가 큰따옴표로 묶여서 작동하지 않으므로 find실행하기 전에 확장됩니다. 문자 그대로 {}로 파이프되었으며 스크립트는 점만 인쇄합니다 awk.awk

명령 대체를하나의따옴표를 사용하면 touch있는 그대로 전달됩니다( find대체만 가능 {}). 매개변수 , 달러 기호, 괄호 등이 touch표시됩니다 . 셸 자체를 통해 명령을 실행하는 것이 아니라 위에서 언급한 대로 명시적으로 실행해야 합니다.-t$(echo ...)find

작은따옴표를 예로 들어 보겠습니다.

$ find -name x -exec echo 'hello $(foo {})' \;
hello $(foo ./x)

관련 정보