Tag Info

Hot answers tagged

20

The quotes protect the contents from shell wildcard expansion. Run that command (or even simpler just echo *test.txt in a directory with a footest.txt file and then one without any files that end in test.txt and you will see the difference. $ ls a b c d e $ echo *test.txt *test.txt $ touch footest.txt $ echo *test.txt footest.txt The same thing will ...


6

Simple use: find . -size +1M -delete If you insist using xargs and rm with find, just add -print0 in your command: find . -size +1M -print0 | xargs -r0 rm -- Other way: find . -size +1M -execdir rm -- {} + From man find: -print0 True; print the full file name on the standard output, followed by a null character (instead of the newline ...


6

you can use the --attributes-only switch of cp for this purpose, eg. find . -iname "*.txt" -exec cp --attributes-only -t dummy/ {} + From the man page of cp: --attributes-only don't copy the file data, just the attributes This will create empty files with all attributes of the original file preserved but no contents.


5

Option -0 of xargs means that output from pipe is interpreted as null terminated items. In such case you also need to create input for the pipe with find ... -print0.


5

The man page for GNU find describes -execdir in part thusly: Like -exec, but the specified command is run from the subdirectory containing the matched file, which is not normally the directory in which you started find. So there is no real subtlety involved. -exec invokes the command from the directory that you run find from (and thus needs to ...


4

Assuming you have the rename command installed, use: find . -name '*"*' -exec rename 's/"//g' {} + The rename command takes a Perl expression to produce the new name. s/"//g performs a global substitution of the name, replacing all the quotes with an empty string. To do it with mv you need to pipe to a shell command, so you can execute subcommands: find ...


3

xargs -0 -I {} mv {} {} | tr -d \" doesn't make sense: mv doesn't produce output. Thus you cannot build pipelines with mv. find . -name '*"*' -exec bash -c 'mv "$1" "${1//\"/}"' bash {} \; or with less overhead find . -name '*"*' -exec bash -c 'for file in "$@"; do mv "$file" "${file//\"/}"; done' bash {} +


3

By default, find includes everything in its search: directories, files, and symlinks. find "/path/to/dir" -mmin -30 -not -name ".*" -exec zip -r "testfile.zip" "{}" \+ If /path/to/dir was modified in the last 30 minutes, it will pass all the tests, and zip, since it was given the -r option, will add the directory and everything under it to the archive. ...


3

In the first case, dump* is interpreted by the shell, and expanded into matching filenames, and then passed to find. In effect, find sees: find dumpa dumpb ... -type f ... In the second case, no interpretation is done by the shell. find does the filtering. Therefore, considering the recursive nature of find, the second method can locate files which the ...


3

You can use find: find /usr -name '0914_Jul-2014.gz' -exec mv {} /var/tmp \; Or for extremely nested directory hierarchies find /usr -name '0914_Jul-2014.gz' -execdir mv {} /var/tmp \; Although as the documentation states you must ensure that your $PATH environment variable does not reference the current directory (namely .) if you use -execdir


2

find(1): -newerXY reference Compares the timestamp of the current file with reference. The reference argument is normally the name of a file (and one of its timestamps is used for the comparison) but it may also be a string describing an absolute time. X and Y are placeholders for other letters, ...


2

Recursing into subdirectories Parsing the output of find is unreliable. What if there was a file name with a newline in it? Use find … -exec …, which guarantees reliable processing. find . -type f -exec sh -c '…' {} \; The shell snippet … receives the file name in $0. Note that this is a separate shell process, it doesn't inherit variables or functions ...


2

Try this with GNU grep: grep -f Pattern.txt File.txt


2

You could convert the filename into something that can be compared directly (such as the Unix timestamp (number of seconds since the epoch), or to YYYYMMDD, which would be lexicographically sortable), and then check if it's older than six months. For example, a script like (say, at /path/to/compare.sh): #! /bin/bash LAST=$(date -d '6 months ago' +%s) for ...


2

Use -type f if you only want regular files. If on a GNU system, the -printf predicate can show you the date. find -maxdepth 1 -type f -mtime -50 -printf "%T+ %p\n"


2

The first directory find /var/tmp finds is /var/tmp. If you want to skip that one (and use Gnu find) then you can change the command to: find /var/tmp -depth -mindepth 1 -type d -ctime -1 -exec rm -rf {} \; or find /var/tmp -mindepth 1 -type d -ctime -1 -exec rm -rf {} \; -prune Without -depth and -prune error messages may occur because rm -rf ...


2

xargs reads data from stdin. When you use rm -i rm also tries to read the answer from stdin (try touch test && echo y | r -i test ; ls test) but stdin is closed by xargs (I assume) so rm reacts as if you had pressed ctrl-d at the prompt. Another solution might be find's -exec option: touch test find . -name test -exec rm -i {} \;


2

You can use getfacl tool with -Recursive option, -skipping files that only have the base ACL and pipe the output to grep. For example the following command run under /dev directory gives for me: $ getfacl -Rs . | awk -v RS= -v ORS='\n\n' '/\nuser:jimmij:rw-\n/' # file: sg1 # owner: root # group: cdrom user::rw- user:jimmij:rw- group::rw- mask::rw- ...


2

You could use find, and tell it to not descent into other filesystems (which should prevent it from accessing virtual filesystems like proc, sys, etc): find / -xdev -uid ${OLD_UID} -execdir chown ${NEW_UID} {} + This may not be as efficient. Another way to filter out the virtual files would be to remount the root filesystem somewhere else: mkdir ...


2

Without recreating the subdirectories: find . -type f -name '*.jpg' -printf /path/to/emptys/%f\\0 | xargs -0 touch


2

To have the security benefit of -execdir (which is really about making sure the command doesn't get a path with several components) and get a prompt, you can use: find . -name hello.c -okdir rm -f {} \; (note that at least the GNU implementation of find doesn't escape filenames in a way suitable for terminals as GNU rm does (wrt control, newline, ...


1

You might do... mkdir ../_cp pax -Xwrl -s'/"//gp' . "${PWD%/*}/_cp" That just creates a bunch of hardlinks to all files in the hierarchy rooted at . in ../_cp. You can then verify everything is well with both directories before removing one of them - they are pretty much the same directories after all, except in one directory there are no filenames which ...


1

Tried to write a Bash script. Please check if it can help you out. #!/bin/bash NOW=`date +%s` last_day() { case $MM in 01|03|05|07|08|10|12 ) echo "31" ;; 04|06|09|11 ) echo "30" ;; 02 ) echo "28" ;; esac } for file in `ls -1 bkp*` do # echo $file DATE=`echo $file | tr -cd [0-9]` # Extract Day of the Month from file name ...


1

I think you do not need to rename the files. You can transform the the filenames on the fly (first sed), compare them to a date (awk) and transform the matching filenames back (second sed). find parent/directory -maxdepth 1 -type d -name 'bkp_*' | \ sed 's#parent/directory/bkp_\(..\)\(..\)\(....\)#\3\2\1#' | \ awk -v date=$(date ...


1

The man page of find says this about -ctime: -ctime n File's status was last changed n*24 hours ago. See the comments for -atime to understand how rounding affects the interpretation of file status change times. and this about -atime: -atime n File was last accessed n*24 hours ago. When find figures out how many ...


1

I'm going to focus on just the removal part of your question. If you have the list of filenames like this: $ cat data.txt 01012000 01022000 01032000 01012014 01022014 01032014 01042014 And you know that the cut off date for 6 months, is say "01022014". You can use sort & sed to determine which files need to be deleted, like so: This will reverse sort ...


1

If you use the -prune option as suggested in this answer, the error message doesn't occur. Quoting from the above answer, Use -prune on the directories that you're going to delete anyway to tell find not to bother trying to find files in them. Testing mkdir koko cd koko touch file{1,2} cd .. find . -type d -name "koko" -prune -exec rm -rf {} \; ...


1

The problem is that find has found a directory, it matches your selection and then the command is executed. However, find wants to do what comes naturally, and that's recursing through a directory tree, but the directory it's just found has disappeared! Hence the error message. You can work around this by supplying the --depth option, which means process ...


1

The recursive grep will scan the entire tree and not care about directory structure. You need to traverse the structure and grep each directory individually. find /var/www -type d -print | while read dirname; do grep -sil '<?' "$dirname"/*.php | head -3; done The grep -s will handle conditions where there are no php files in a directory.


1

You can use xargs to feed the output of a command as arguments to another: find . -iname '*.txt' -print0 | xargs -0 tar zcvf the_tarball.tar.gz Note here the -print0 from find and -0 from xargs work in conjunction to delimit file names correctly (so that names with spaces and such aren't a problem).



Only top voted, non community-wiki answers of a minimum length are eligible