Forums

Skip to content

Advanced search
  • Quick links
    • Unanswered topics
    • Active topics
    • Search
  • FAQ
  • Login
  • Register
  • Board index Assistance Portage & Programming
  • Search

Follies with find

Problems with emerge or ebuilds? Have a basic programming question about C, PHP, Perl, BASH or something else?
Post Reply
Advanced search
11 posts • Page 1 of 1
Author
Message
curmudgeon
Veteran
Veteran
Posts: 1746
Joined: Fri Aug 08, 2003 1:39 pm

Follies with find

  • Quote

Post by curmudgeon » Sun Jun 13, 2010 10:44 am

I am trying to use find to do something where I need each file as an argument twice.

For an example, let's suppose I wanted to set all of the access times in a tree equal to the modification time.

I thought something like this would work (but it doesn't):

Code: Select all

$ find /usr/local/portage/sys-kernel/gentoo-sources/ -exec touch -d "`date -r {}`" {} ';'
Sure, I could do this (fairly easily even) in two steps - do the find, listing the files and the dates (saving the output to a file), and then editing the file (turning it into a script by putting the touch command at the front of each line), but I am looking for an elegant (meaning one command) solution.

Any ideos?
Top
jongeek
Tux's lil' helper
Tux's lil' helper
Posts: 135
Joined: Fri Jul 13, 2007 11:12 pm
Location: The Humid, Festering Swamps of Florida

  • Quote

Post by jongeek » Sun Jun 13, 2010 12:18 pm

Ok, so I don't know how to do it with one command, but you can use bash to do it in one line.

Code: Select all

for file in $(find /usr/local/portage/sys-kernel/gentoo-sources); do touch -d "$(date -r ${file})" ${file}; done
I hope that follows the spirit of your request, if not the letter.
Top
aderesch
Tux's lil' helper
Tux's lil' helper
Posts: 123
Joined: Sat Mar 06, 2010 10:58 am
Location: Hamburg, Germany

Re: Follies with find

  • Quote

Post by aderesch » Sun Jun 13, 2010 12:28 pm

curmudgeon wrote:I am trying to use find to do something where I need each file as an argument twice.

Code: Select all

$ find /usr/local/portage/sys-kernel/gentoo-sources/ -exec touch -d "`date -r {}`" {} ';'
Your problem isn't using an argument twice, but rather the backticks (command substitution).
This should do, although it's not elegant:

Code: Select all

find -exec bash -c 'touch -d "`date -r "{}"`" "{}"' \;
ad

Edit: Plus it is of course inefficient, but that's not what you asked. :-) So in reality I would also prefer the above for-loop approach.
Edit2: Changed to use single quotes instead of lots of escaping.
Last edited by aderesch on Sun Jun 13, 2010 4:38 pm, edited 1 time in total.
Top
Akkara
Bodhisattva
Bodhisattva
User avatar
Posts: 6702
Joined: Tue Mar 28, 2006 12:27 pm
Location: &akkara

  • Quote

Post by Akkara » Sun Jun 13, 2010 12:48 pm

A idiom I like to use for such things goes like this:

Code: Select all

fine $DIR ...conditions... -print | while read F; do
    echo "$F" "and again" "$F"
done
This works even for files and paths with spaces and special characters in the name (but not if there's a newline in the name).
Top
mv
Watchman
Watchman
User avatar
Posts: 6795
Joined: Wed Apr 20, 2005 12:12 pm

  • Quote

Post by mv » Sun Jun 13, 2010 4:03 pm

And the right way to do things like this (which works however the filename looks like) is the following:

Code: Select all

find /usr/local/portage/sys-kernel/gentoo-sources/ -exec /bin/sh -c 'for i
do	touch -d "`date -r -- "${i}"`" -- "${i}"
done' sh '{}'  '+'
Of course, changing the date of the file to its own date makes no change, but I suppose this was just an example (in connection with "touch" you will problably want to use the find option -depth anyway).
Top
curmudgeon
Veteran
Veteran
Posts: 1746
Joined: Fri Aug 08, 2003 1:39 pm

  • Quote

Post by curmudgeon » Sun Jun 13, 2010 8:33 pm

mv wrote:Of course, changing the date of the file to its own date makes no change, but I suppose this was just an example (in connection with "touch" you will problably want to use the find option -depth anyway).
It's supposed to, but it doesn't seem to work.

From the man page:

Update the access and modification times...

But:

Code: Select all

# ls -cl gentoo-sources-2.6.32-r7.ebuild
-rw-r--r-- 1 portage portage 899 2010-06-13 20:22:24 gentoo-sources-2.6.32-r7.ebuild

# touch -d 2010-04-10 gentoo-sources-2.6.32-r7.ebuild

# ls -cl gentoo-sources-2.6.32-r7.ebuild
-rw-r--r-- 1 portage portage 899 2010-06-13 20:23:08 gentoo-sources-2.6.32-r7.ebuild
I get similar results trying touch -a -d.
Top
mv
Watchman
Watchman
User avatar
Posts: 6795
Joined: Wed Apr 20, 2005 12:12 pm

  • Quote

Post by mv » Sun Jun 13, 2010 9:55 pm

ls -cl shows the ctime; this is neither the atime nor the mtime.
Top
Hu
Administrator
Administrator
Posts: 24385
Joined: Tue Mar 06, 2007 5:38 am

  • Quote

Post by Hu » Sun Jun 13, 2010 9:58 pm

Akkara wrote:(but not if there's a newline in the name).
For that, use -print0 and read -d $'\0' to generate and read null terminated records. This requires GNU find and bash, rather than just find and POSIX sh as yours does, but should get the job done if those requirements are satisfied. Unlike the construct proposed by mv, this lets you retain a find/while read pattern, thus avoiding the creation of one shell per record.
Top
mv
Watchman
Watchman
User avatar
Posts: 6795
Joined: Wed Apr 20, 2005 12:12 pm

  • Quote

Post by mv » Sun Jun 13, 2010 10:19 pm

Hu wrote:to generate and read null terminated records. [...]
Unlike the construct proposed by mv, this lets you retain a find/while read pattern, thus avoiding the creation of one shell per record.
In the first sentence you seem to mean by "record" 1 filename. However, in the solution which I posted, one record is typically several thousand filenames (determined by the maximal length of a command). Moreover, you save some time since you do not need to send the data over a pipe and can use dash (much faster than bash, especially when spawning); which solution is actually faster altogether depends on a lot of unknown data. So if in doubt, I would prefer the compatible solution over the GNUism.
Top
Hu
Administrator
Administrator
Posts: 24385
Joined: Tue Mar 06, 2007 5:38 am

  • Quote

Post by Hu » Sun Jun 13, 2010 11:55 pm

mv wrote:However, in the solution which I posted, one record is typically several thousand filenames (determined by the maximal length of a command). Moreover, you save some time since you do not need to send the data over a pipe and can use dash (much faster than bash, especially when spawning); which solution is actually faster altogether depends on a lot of unknown data. So if in doubt, I would prefer the compatible solution over the GNUism.
Indeed, I overlooked your use of the SVR4 variation. Too often, I see people use the traditional model of spawning one process per filename.
Top
curmudgeon
Veteran
Veteran
Posts: 1746
Joined: Fri Aug 08, 2003 1:39 pm

  • Quote

Post by curmudgeon » Thu Jun 17, 2010 1:29 pm

mv wrote:ls -cl shows the ctime; this is neither the atime nor the mtime.
Oops. Guess I didn't understand that too well (just did a bunch more reading on the subject).

It seems this would be the tool to manipulate timestamps:

http://stroke.sourceforge.net/
Top
Post Reply

11 posts • Page 1 of 1

Return to “Portage & Programming”

Jump to
  • Assistance
  • ↳   News & Announcements
  • ↳   Frequently Asked Questions
  • ↳   Installing Gentoo
  • ↳   Multimedia
  • ↳   Desktop Environments
  • ↳   Networking & Security
  • ↳   Kernel & Hardware
  • ↳   Portage & Programming
  • ↳   Gamers & Players
  • ↳   Other Things Gentoo
  • ↳   Unsupported Software
  • Discussion & Documentation
  • ↳   Documentation, Tips & Tricks
  • ↳   Gentoo Chat
  • ↳   Gentoo Forums Feedback
  • ↳   Duplicate Threads
  • International Gentoo Users
  • ↳   中文 (Chinese)
  • ↳   Dutch
  • ↳   Finnish
  • ↳   French
  • ↳   Deutsches Forum (German)
  • ↳   Diskussionsforum
  • ↳   Deutsche Dokumentation
  • ↳   Greek
  • ↳   Forum italiano (Italian)
  • ↳   Forum di discussione italiano
  • ↳   Risorse italiane (documentazione e tools)
  • ↳   Polskie forum (Polish)
  • ↳   Instalacja i sprzęt
  • ↳   Polish OTW
  • ↳   Portuguese
  • ↳   Documentação, Ferramentas e Dicas
  • ↳   Russian
  • ↳   Scandinavian
  • ↳   Spanish
  • ↳   Other Languages
  • Architectures & Platforms
  • ↳   Gentoo on ARM
  • ↳   Gentoo on PPC
  • ↳   Gentoo on Sparc
  • ↳   Gentoo on Alternative Architectures
  • ↳   Gentoo on AMD64
  • ↳   Gentoo for Mac OS X (Portage for Mac OS X)
  • Board index
  • All times are UTC
  • Delete cookies

© 2001–2026 Gentoo Foundation, Inc.

Powered by phpBB® Forum Software © phpBB Limited

Privacy Policy