파일 이름에 파일 생성 날짜( )가 포함된 파일이 많이 있습니다 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)