Hot answers tagged

13

Try: grep -rl --null --include '*.txt' LINUX/UNIX . | xargs -0r cp -t /path/to/dest Because this command uses NUL-separation, it is safe for all file names including those with difficult names that include blanks, tabs, or even newlines. The above requires GNU cp. For BSD/OSX, try: grep -rl --null --include '*.txt' LINUX/UNIX . | xargs -0 sh -c 'cp "$@"...


12

More portably (POSIX features only): find . -type f -name '*.txt' -exec grep -q LINUX/UNIX \; -exec cp {} /path/to/dest \;


5

Using GNU find: #!/bin/sh dir='/mnt/data/project_data/web_collab/mailbox/' sr_today=$(find "$dir" \ ! -path '*/000000/*' \ -newermt '12am today' \ -ipath '*/sr_pdf/*.pdf' | wc -l) GNU find's -newermt option understands the same date formats as GNU date -d and touch -d. See man find and search for -...


4

find . -depth -iname proj -type d -execdir mv {} test \; You need a find implementation with support for the non-standard -execdir predicate, but find implementations that support -iname generally also support -execdir in my experience.


4

If you have GNU find, you can print the path using the %h format specifier %h Leading directories of file's name (all but the last ele‐ ment). If the file name contains no slashes (since it is in the current directory) the %h specifier expands to ".". So for example you could do find . -name 'results.out' -...


3

To get ls to display the folder name instead of listing its contents, use its -d argument such as: ls -ld ~


2

The following sh/Bash one liner is another method, though will only work in the current directory, and doesn't recurse: for f in ./*.txt; do if grep -l 'LINUX/UNIX' "$f"; then cp "$f" /path/to/dest/; fi; done The -l option to grep will print a list of the files which are being copied, though you could use -q if you don't want to see anything on the screen....


2

With your version of find, the {} in the string is replaced by the file name. It is almost always an error to use {} as part of a string, because the file name is inserted just like that. Here, the file name is used as a shell script fragment. If there's a directory called a'$(touch wibble)' then your command executes the shell code pwd; echo 'a'$(touch ...


2

Change it like this: find pictures -type d -links 2 -execdir \ sh -c 'pwd; echo "$1"; zip -vr "$1/$1.zip" "$1" -x \*.zip -x \*.id' sh {} \;


2

Without ls, in bash, or some other shell that has arrays (this should work even with names that have funny characters in them): $ names=( my.parent/my.folder* ); echo ${names[-1]} my.parent/my.folder2 Without arrays (not so robust against funny characters, but saves a fork of the ls): $ printf "%s\n" my.parent/my.folder* | tail -1 my.parent/my.folder2


2

First, if you're going to be using a long path like that, it's best to give it its own variable name. Makes the code easier to read, makes sure you use the same name everywhere without typos, and makes it easier to change if you need. MAILBOX=/mnt/data/project_data/web_collab/mailbox Try this if there's less than a few hundred pdf files to contend with: ...


2

With zsh: print -rl ./**/results.out(.e_'grep -q string $REPLY'_:h) this searches recursively for regular files (.) named results.out, runs grep -q ... on each of them and if that evaluates true it prints only the head of the path (the path without the last element). Another way with find and sh, using parameter expansion to extract the head: find . -...


1

for i in $(find . -type f -name "results.out); do grep -l "string1" $i ; exitcode=${?} if [ ${exitcode} -eq 0 ] # string1 is found in file $i then path=${i%/*} echo ${path} fi done


1

find . type -f ! -name '*.jpeg' ! -name '*.csv' -delete Read this as: traverse the current directory; when you find a file that is a regular file, and whose name does not match *.jpeg, and whose name is does not match *.csv, then delete it. If your version of find doesn't have -delete, make find invoke the rm command: replacte -delete by -exec rm {} +. ...


1

With GNU find: find . -name '*.log' -printf '%p,%s\n' That will print the filename and the file's size in bytes, separated by a comma. Use %f instead of %p if you only want the file's basename (i.e. without the path). To display as kilobytes (units of 10^3, "KB") or kibibytes (units of 2^10, "KiB"), you'll need to post-process the output. See A ...


1

find . -name '.git' -prune is the same as find . -name '.git' -prune -print so it prunes and then prints find . -name '.git' -prune -o -name '*.md' -print is the same as find . \( -name '.git' -prune -true \) -o \( -name '*.md' -print \) so it does first clause, if it does prune then it does true (prune returns true), and does not do right hand ...



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