Set file modification date from date stored as filename

Clash Royale CLAN TAG#URR8PPP
up vote
0
down vote
favorite
I have a lot of files where filename contains file creation date (IMG_RRRRMMDD_hhmmss.jpg):
IMG_20171015_133516.jpg
IMG_20171015_133827.jpg
IMG_20171015_142634.jpg
IMG_20171015_142834.jpg
IMG_20171015_142857.jpg
but actual file creation date is different. I need to set it back to date from a filename.
I know how to change the date of all files to current date:
find -type f -exec touch ;
and how to parse the file name to get the date in the proper format for touch -t
echo IMG_20171015_133516.jpg | awk -F_ 'print $2 substr($3,0,4) "." substr($3,5,2)'
201710151335.16
But I have no idea how to combine these commands together to change all files.
find -type f -exec touch -t"$(echo '' | awk -F_ 'print $2 substr($3,0,4) "." substr($3,5,2)')" ;
returns
touch: invalid date format âÂÂ.âÂÂ
awk files find date touch
add a comment |Â
up vote
0
down vote
favorite
I have a lot of files where filename contains file creation date (IMG_RRRRMMDD_hhmmss.jpg):
IMG_20171015_133516.jpg
IMG_20171015_133827.jpg
IMG_20171015_142634.jpg
IMG_20171015_142834.jpg
IMG_20171015_142857.jpg
but actual file creation date is different. I need to set it back to date from a filename.
I know how to change the date of all files to current date:
find -type f -exec touch ;
and how to parse the file name to get the date in the proper format for touch -t
echo IMG_20171015_133516.jpg | awk -F_ 'print $2 substr($3,0,4) "." substr($3,5,2)'
201710151335.16
But I have no idea how to combine these commands together to change all files.
find -type f -exec touch -t"$(echo '' | awk -F_ 'print $2 substr($3,0,4) "." substr($3,5,2)')" ;
returns
touch: invalid date format âÂÂ.âÂÂ
awk files find date touch
add a comment |Â
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I have a lot of files where filename contains file creation date (IMG_RRRRMMDD_hhmmss.jpg):
IMG_20171015_133516.jpg
IMG_20171015_133827.jpg
IMG_20171015_142634.jpg
IMG_20171015_142834.jpg
IMG_20171015_142857.jpg
but actual file creation date is different. I need to set it back to date from a filename.
I know how to change the date of all files to current date:
find -type f -exec touch ;
and how to parse the file name to get the date in the proper format for touch -t
echo IMG_20171015_133516.jpg | awk -F_ 'print $2 substr($3,0,4) "." substr($3,5,2)'
201710151335.16
But I have no idea how to combine these commands together to change all files.
find -type f -exec touch -t"$(echo '' | awk -F_ 'print $2 substr($3,0,4) "." substr($3,5,2)')" ;
returns
touch: invalid date format âÂÂ.âÂÂ
awk files find date touch
I have a lot of files where filename contains file creation date (IMG_RRRRMMDD_hhmmss.jpg):
IMG_20171015_133516.jpg
IMG_20171015_133827.jpg
IMG_20171015_142634.jpg
IMG_20171015_142834.jpg
IMG_20171015_142857.jpg
but actual file creation date is different. I need to set it back to date from a filename.
I know how to change the date of all files to current date:
find -type f -exec touch ;
and how to parse the file name to get the date in the proper format for touch -t
echo IMG_20171015_133516.jpg | awk -F_ 'print $2 substr($3,0,4) "." substr($3,5,2)'
201710151335.16
But I have no idea how to combine these commands together to change all files.
find -type f -exec touch -t"$(echo '' | awk -F_ 'print $2 substr($3,0,4) "." substr($3,5,2)')" ;
returns
touch: invalid date format âÂÂ.âÂÂ
awk files find date touch
edited Dec 7 '17 at 20:14
Jeff Schaller
32k848109
32k848109
asked Dec 7 '17 at 20:01
mx0
1837
1837
add a comment |Â
add a comment |Â
1 Answer
1
active
oldest
votes
up vote
5
down vote
accepted
In the shell:
for f in ./IMG_*.jpg ; do
t=$f##*/
touch "$f" -t "$t:4:8$t:13:4.$t:17:2"
done
Bash, ksh, zsh etc have the $var:n:m substring expansion, and if you need to do it recursively, enable globstar and use **/IMG_*.jpg instead.
Doing it with find needs the shell, too:
$ 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 +
The first argument to Bash after the script goes to the $0 variable, which usually contains the shell name. The rest go to the positional parameters $1, $2, etc. and for f or for f in "$@" loops over them.
The construct is here is rather common (at least in unix.SE answers).
The main part of the loop here is the same as in the first example.
The find command in your question find .. -exec touch -t"$(...)" ; doesn't work since the command substitution is in double quotes, so it gets expanded before find runs. The is piped literally to awk, and it just so happens that the awk script only prints a dot.
If you did put the command substitution in single quotes, it would be passed to touch as-is (find would only substitute ). touch would get the argument -t$(echo ...), dollar signs, parenthesis and all. find doesn't run the command through the shell by itself, we need to explicitly do it, as above.
In single quotes example:
$ find -name x -exec echo 'hello $(foo )' ;
hello $(foo ./x)
Works great, but I still don't know what's wrong with my approach. Why "$()" returns.instead formatted date?
â mx0
Dec 8 '17 at 15:50
@mx0, ah good point, perhaps that should have been elaborated. edited.
â ilkkachu
Dec 8 '17 at 16:00
Ok, now I get it, Thanks for fast response.
â mx0
Dec 8 '17 at 16:10
add a comment |Â
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
5
down vote
accepted
In the shell:
for f in ./IMG_*.jpg ; do
t=$f##*/
touch "$f" -t "$t:4:8$t:13:4.$t:17:2"
done
Bash, ksh, zsh etc have the $var:n:m substring expansion, and if you need to do it recursively, enable globstar and use **/IMG_*.jpg instead.
Doing it with find needs the shell, too:
$ 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 +
The first argument to Bash after the script goes to the $0 variable, which usually contains the shell name. The rest go to the positional parameters $1, $2, etc. and for f or for f in "$@" loops over them.
The construct is here is rather common (at least in unix.SE answers).
The main part of the loop here is the same as in the first example.
The find command in your question find .. -exec touch -t"$(...)" ; doesn't work since the command substitution is in double quotes, so it gets expanded before find runs. The is piped literally to awk, and it just so happens that the awk script only prints a dot.
If you did put the command substitution in single quotes, it would be passed to touch as-is (find would only substitute ). touch would get the argument -t$(echo ...), dollar signs, parenthesis and all. find doesn't run the command through the shell by itself, we need to explicitly do it, as above.
In single quotes example:
$ find -name x -exec echo 'hello $(foo )' ;
hello $(foo ./x)
Works great, but I still don't know what's wrong with my approach. Why "$()" returns.instead formatted date?
â mx0
Dec 8 '17 at 15:50
@mx0, ah good point, perhaps that should have been elaborated. edited.
â ilkkachu
Dec 8 '17 at 16:00
Ok, now I get it, Thanks for fast response.
â mx0
Dec 8 '17 at 16:10
add a comment |Â
up vote
5
down vote
accepted
In the shell:
for f in ./IMG_*.jpg ; do
t=$f##*/
touch "$f" -t "$t:4:8$t:13:4.$t:17:2"
done
Bash, ksh, zsh etc have the $var:n:m substring expansion, and if you need to do it recursively, enable globstar and use **/IMG_*.jpg instead.
Doing it with find needs the shell, too:
$ 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 +
The first argument to Bash after the script goes to the $0 variable, which usually contains the shell name. The rest go to the positional parameters $1, $2, etc. and for f or for f in "$@" loops over them.
The construct is here is rather common (at least in unix.SE answers).
The main part of the loop here is the same as in the first example.
The find command in your question find .. -exec touch -t"$(...)" ; doesn't work since the command substitution is in double quotes, so it gets expanded before find runs. The is piped literally to awk, and it just so happens that the awk script only prints a dot.
If you did put the command substitution in single quotes, it would be passed to touch as-is (find would only substitute ). touch would get the argument -t$(echo ...), dollar signs, parenthesis and all. find doesn't run the command through the shell by itself, we need to explicitly do it, as above.
In single quotes example:
$ find -name x -exec echo 'hello $(foo )' ;
hello $(foo ./x)
Works great, but I still don't know what's wrong with my approach. Why "$()" returns.instead formatted date?
â mx0
Dec 8 '17 at 15:50
@mx0, ah good point, perhaps that should have been elaborated. edited.
â ilkkachu
Dec 8 '17 at 16:00
Ok, now I get it, Thanks for fast response.
â mx0
Dec 8 '17 at 16:10
add a comment |Â
up vote
5
down vote
accepted
up vote
5
down vote
accepted
In the shell:
for f in ./IMG_*.jpg ; do
t=$f##*/
touch "$f" -t "$t:4:8$t:13:4.$t:17:2"
done
Bash, ksh, zsh etc have the $var:n:m substring expansion, and if you need to do it recursively, enable globstar and use **/IMG_*.jpg instead.
Doing it with find needs the shell, too:
$ 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 +
The first argument to Bash after the script goes to the $0 variable, which usually contains the shell name. The rest go to the positional parameters $1, $2, etc. and for f or for f in "$@" loops over them.
The construct is here is rather common (at least in unix.SE answers).
The main part of the loop here is the same as in the first example.
The find command in your question find .. -exec touch -t"$(...)" ; doesn't work since the command substitution is in double quotes, so it gets expanded before find runs. The is piped literally to awk, and it just so happens that the awk script only prints a dot.
If you did put the command substitution in single quotes, it would be passed to touch as-is (find would only substitute ). touch would get the argument -t$(echo ...), dollar signs, parenthesis and all. find doesn't run the command through the shell by itself, we need to explicitly do it, as above.
In single quotes example:
$ find -name x -exec echo 'hello $(foo )' ;
hello $(foo ./x)
In the shell:
for f in ./IMG_*.jpg ; do
t=$f##*/
touch "$f" -t "$t:4:8$t:13:4.$t:17:2"
done
Bash, ksh, zsh etc have the $var:n:m substring expansion, and if you need to do it recursively, enable globstar and use **/IMG_*.jpg instead.
Doing it with find needs the shell, too:
$ 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 +
The first argument to Bash after the script goes to the $0 variable, which usually contains the shell name. The rest go to the positional parameters $1, $2, etc. and for f or for f in "$@" loops over them.
The construct is here is rather common (at least in unix.SE answers).
The main part of the loop here is the same as in the first example.
The find command in your question find .. -exec touch -t"$(...)" ; doesn't work since the command substitution is in double quotes, so it gets expanded before find runs. The is piped literally to awk, and it just so happens that the awk script only prints a dot.
If you did put the command substitution in single quotes, it would be passed to touch as-is (find would only substitute ). touch would get the argument -t$(echo ...), dollar signs, parenthesis and all. find doesn't run the command through the shell by itself, we need to explicitly do it, as above.
In single quotes example:
$ find -name x -exec echo 'hello $(foo )' ;
hello $(foo ./x)
edited Dec 8 '17 at 15:59
answered Dec 7 '17 at 20:16
ilkkachu
50.1k676138
50.1k676138
Works great, but I still don't know what's wrong with my approach. Why "$()" returns.instead formatted date?
â mx0
Dec 8 '17 at 15:50
@mx0, ah good point, perhaps that should have been elaborated. edited.
â ilkkachu
Dec 8 '17 at 16:00
Ok, now I get it, Thanks for fast response.
â mx0
Dec 8 '17 at 16:10
add a comment |Â
Works great, but I still don't know what's wrong with my approach. Why "$()" returns.instead formatted date?
â mx0
Dec 8 '17 at 15:50
@mx0, ah good point, perhaps that should have been elaborated. edited.
â ilkkachu
Dec 8 '17 at 16:00
Ok, now I get it, Thanks for fast response.
â mx0
Dec 8 '17 at 16:10
Works great, but I still don't know what's wrong with my approach. Why "$()" returns
. instead formatted date?â mx0
Dec 8 '17 at 15:50
Works great, but I still don't know what's wrong with my approach. Why "$()" returns
. instead formatted date?â mx0
Dec 8 '17 at 15:50
@mx0, ah good point, perhaps that should have been elaborated. edited.
â ilkkachu
Dec 8 '17 at 16:00
@mx0, ah good point, perhaps that should have been elaborated. edited.
â ilkkachu
Dec 8 '17 at 16:00
Ok, now I get it, Thanks for fast response.
â mx0
Dec 8 '17 at 16:10
Ok, now I get it, Thanks for fast response.
â mx0
Dec 8 '17 at 16:10
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f409564%2fset-file-modification-date-from-date-stored-as-filename%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password