
Bash can be really frustrating!
I'm trying to take all the files that match a pattern and put them in a tar.gz file. Sounds simple?
aj@aj-laptop:/home/aj$ find . -name "*tips*"Apparently it would not work fine when your filenames have spaces in them because then it would tokenise them with spaces and hence break up the file names.
./data/DRAFT/tips and tricks.doc
./data/DRAFT/tips new.doc
Looks okay till here. But -
aj@aj-laptop:/home/aj$ find . -name "*tips*" | xargs tar czvvf tips.tar.gz
tar: ./data/DRAFT/tips: Cannot stat: No such file or directory
tar: and: Cannot stat: No such file or directory
tar: tricks.doc: Cannot stat: No such file or directory
tar: ./data/DRAFT/tips: Cannot stat: No such file or directory
tar: new.doc: Cannot stat: No such file or directory
tar: Error exit delayed from previous errors
aj@aj-laptop:/home/aj$
So I search around on the web and find a bunch of things to try on a stackoverflow thread.
And here's the solution that worked -
aj@aj-laptop:/home/aj$ find . -name "*tips*" -print0 | xargs -0 tar czvvf tips.tar.gzBasically adding -print0 to the find command makes it separate strings by NULLs (\0s) which can never be a part of the filenames and can never cause problems.Note that you also need to tell xargs to separate strings by NULLs by passing the -0 flag.
-rwx------ aj/aj 31232 2010-01-12 19:23 ./data/DRAFT/tips and tricks.doc
-rwx------ aj/aj 30208 2008-10-08 16:57 ./data/DRAFT/tips new.doc
aj@aj-laptop:/home/aj$
But now since I couldn't find any such flags for other standard linux commands like grep, this solution is only useful when I need to pass the output from find straight into tar. For example I cannot do find . -name "*tips*" -print0 | grep 'tricks' | xargs -0 tar czvvf tips_and_tricks.tar.gz !
Sad! But I am done for the day with this problem. Please let me know in the comments if there is a general solution to this.
3 comments:
I found this when looking for something totally different, but I can help you.
The problem is that you're using xargs. Tar is made to read a list of files from stdin.
Simply pass "-T -" as an argument, avoid the overhead of xargs, and you're good to go!
LOL! Nice pic!!! You dont mind if I borrow it :p
Post a Comment