Results 1 to 5 of 5
Hi all, I'm writing a script to preserve the creation dates of the files to be converted to other formats. For the names of the converted files, I believe these ...
- 08-12-2008 #1Linux User
- Join Date
- May 2008
- Location
- NYC, moved from KS & MO
- Posts
- 251
problem with passing argument to -exec in find command
Hi all, I'm writing a script to preserve the creation dates of the files to be converted to other formats. For the names of the converted files, I believe these are the most common patterns, for example,
- *.doc -> *.txt
- *.doc - > *.doc.txt
and I came up with this bash script
It works only in the append mode. For example, if I do aCode:#!/bin/bash # script name: fixdate usage() { echo "usage: `basename $0` src_path src_ext dest_path dest_ext [append|replace]" } MODE="replace" case $# in 5|4) [ $# -eq 5 ] && MODE=$5 case $MODE in append) find $1 -name "*.$2" -exec touch -c -r {} $3/`basename {}`.$4 \; ;; replace) find $1 -name "*.$2" -exec touch -c -r {} $3/`basename {} $2`$4 \; ;; *) usage ;; esac ;; *) usage ;; esac
, it works as expected, that is, creation dates of ./*.txt got replaced with those of ./*.txt.docCode:fixdate . doc . txt append
But when I try to run
, orCode:fixdate . doc . txt replace
, the creation dates of ./*.txt don't get replaced by those of ./*.docCode:fixdate . doc . txt
I can work around this by changing the bold line in the script into
I kind of know that $2 in the original code didn't get passed into `basename` in -exec under replace mode but I don't know exactly why and I hope someone could point out what the problem is. Thank you.Code:find $1 -name "*.$2" | while read F; do touch -c -r $F $3/`basename $F $2`$4; done
- 08-12-2008 #2Linux Newbie
- Join Date
- Jul 2008
- Posts
- 181
Shouldn't that be
Code:find $1 -name "*.$2" -exec touch -c -r {} $3/`basename {}`$2 $4 \;
- 08-12-2008 #3Linux User
- Join Date
- May 2008
- Location
- NYC, moved from KS & MO
- Posts
- 251
- 08-13-2008 #4Linux Newbie
- Join Date
- Jul 2008
- Posts
- 181
Right. I'm afraid that won't work, as the "{}" has not yet been replaced by the filename found when you call basename. It might be a better idea to generate a list of matching filenames and then feed it to touch via a loop, e.g.
Code:find -name whatever | while read filename; do manipulate filename; touch -cr oldname newname; done
- 08-13-2008 #5Linux User
- Join Date
- May 2008
- Location
- NYC, moved from KS & MO
- Posts
- 251
My final version of this script:
This improved version takes care of the argument passing problem, also the modifications apply to only files, whose names might contain space(s).Code:#!/bin/bash # script to change converted files' creation dates # usage: # fixdate src_path src_ext dest_path dest_ext [append|replace] usage() { echo "usage:" echo " `basename $0` src_path src_ext dest_path dest_ext [append|replace]" echo " by default, replace mode will be used, that is, for example, converted files are in *.txt format while the origins are *.doc format" echo " alternatively, append mode can be specified if the converted files are in *.doc.txt format" echo "example:" echo " `basename $0` . doc converted/ txt" echo " set the dates of *.txt under converted/ to be the same as those of ./*.doc" echo "note:" echo " filenames/paths in this script are case sensitive" } MODE="replace" case $# in 5|4) [ $# -eq 5 ] && MODE=$5 case $MODE in append) find $1 -name "*.$2" -type f | while read F; do dest_name=$3/`basename "$F"`.$4; touch -c -r "$F" "${dest_name}"; done ;; replace) find $1 -name "*.$2" -type f | while read F; do dest_name=$3/`basename "$F" $2`$4; touch -c -r "$F" "${dest_name}"; done ;; *) usage ;; esac ;; *) usage ;; esac


Reply With Quote
