Tag Info

New answers tagged

2

While the other options are fine, I'd like to correct some mistakes in your approach: userid=$(cat $uidscript|cut -c1 -d':'): -c gets characters, you need fields. Use cut -f1 -d:. Useless use of cat: Just do: cut -f1 -d: <"$uidscript". Store the result in an array so you can iterate over it and another array easily: IFS=$'\n' # split on newline set ...


3

Use a while-read loop to process the lines of the file while IFS=: read userid filename do find . -user "$userid" -name "$filename" done < "$uidscript"


2

You could do: IFS=: # split on : set -f # disable glob part of the split+glob operator echo find . $( awk -F: ' { printf "%s", sep "(:-user:" $1 ":-name:" $2 ":):" sep = "-o:" }' < "$uidfile") (remove the echo if that's the right command you want to run).


3

You don't need xargs at all, just use exec option: find . -maxdepth 1 -name "*.md" -exec aspell check {} \; And just in case you, or any future reader, will really need to use xargs - you can do that by spawning new shell and taking standard input from terminal (/dev/tty): find . -maxdepth 1 -name "*.sh" | xargs -n1 sh -c 'aspell check "$@" < ...


1

You could always just use a simple loop: for f in *.md; do aspell check "$f"; done


1

If you want to test for any of the bits, use /. I.e. for your use case: find $DIRECTORY -perm /4000 and: find $DIRECTORY -perm /2000 or combined: find $DIRECTORY -perm /6000 You may use both folders and files as argument for GNU find. Another, IMO better readable, approach is using the mnemonic shortcuts. I.e.: find $DIRECTORY -perm /u=s,g=s ...


3

man rsync says about --files-from: The filenames that are read from the FILE are all relative to the source dir -- any leading slashes are removed and no ".." references are allowed to go higher than the source dir. So try making the paths output by find relative: rsync -avz ... --files-from=<(ssh user@remote1 'cd /home/admin/Backup/; ...


5

With GNU find: find . -name foo.mp4 -printf '%h\n' With other finds, provided directory names don't contain newline characters: find . -name foo.mp4 | sed 's|/[^/]*$||' Or: find . -name foo.mp4 -exec dirname {} \; though that means running one dirname command per file. If you need to run a command on that path, you can do (standard syntax): ...


0

According to tftp's help you can't: tftp> ? Commands may be abbreviated. Commands are: connect connect to remote tftp mode set file transfer mode put send file get receive file quit exit tftp verbose toggle verbose mode trace toggle packet tracing status show current ...


2

Decision1: Use GNU sed instead of awk sed -i -e '1 i\line1\nline2' -e '$ a\line3\nline4' ./* Decision2: Use loop for for each file in directory for file in ./* do awk ' BEGIN { print "line1\nline2" } { print $0 } END { print "line3\nline4" } ' "$file" > "$file".tmp && mv -f "$file".tmp "$file" done


6

With GNU awk 4.1 or above: find . -type f -exec awk ' @load "inplace" BEGINFILE { inplace_begin(FILENAME, "") print "line1\nline2" } {print} ENDFILE { print "line3\nline4" inplace_end(FILENAME, "") }' {} +


0

Found the solution find . -regex '.*test.*s01e[0-9][0-9].*720p.*x264.*' -exec cp {} /storage/tv/test/s01/ \;


0

GNU findutils uses Emacs style regex, so out of box, this should suffice: find . -regex '.*test.s01e[0-9][0-9]' -exec cp {} /storage/tv/test/s01 \;


0

There's no built-in feature of find to analyze the file content, but you can make it invoke file. Using the shell to combine multiple task-specific programs (find to traverse directory trees, file to analyze file content) is the Unix way of doing things. You want to act on files for which the output of the command file -b -- "$filename" contains the string ...


0

This doesn't use find, but setting pattern and directory will produce the results your question asks for: pattern="PalmOS application" directory=. for f in $directory/*; do if [[ $(file -b $f) == "$pattern" ]]; then echo $f; fi; done


3

Something along the lines of: find . -print -exec file {} \; | grep "PalmOS" To tidy up the output pipe through awk as well by adding: | awk '{print substr($1,2,length($1)-2)}'


2

You can also use gnu stow, a symlink farm manager. Assume the following layout: . ├── drive │   ├── a │   │   ├── b │   │   │   └── bar │   │   └── c │   │   └── baz │   └── b └── music └── a └── b └── foo Execute: $ stow --target music --dir drive . Result: . ├── drive │   ├── a │   │   ├── b │   │   │   └── bar │   │   └── ...


1

Try using ps to look for the sleep command: { sleep 20; find ...; } & parent=$! if ps --ppid $parent | grep sleep then echo Sleep is running fi


2

{ touch /tmp/sleep.flag; sleep 2d ; rm /tmp/sleep.flag; find /home/disk1/ -exec touch {} \; ; } & Everything what you need just check /tmp/sleep.flag file existance [ -f /tmp/sleep.flag ] && echo "Running sleep..."


0

You might try this as well . Considering the test directory is in the same directory with other directories , find . -mindepth 2 ! -name test -exec cp {} test \; This will copy all individual files to the directory test , escaping the dir1 , dir2 etc. Note that this will omit subdirectories itself and copies contents of them. you can also test this by ...


4

Since your primary aim is to have a combined view of your local and external Music folder, I think a union mount via overlayfs could be used, especially if the files are not being written to. The basic command is, in older kernel versions (<3.18): mount -t overlayfs -o lowerdir=/read/only/directory,upperdir=/writeable/directory overlayfs /mount/point ...


2

Try: $ find -type d -name '*dir*' -exec sh -c ' for d do for f in "$d"/*; do [ -f "$f" ] && mv -- "$f" /path/to/test done done ' sh {} +


2

mv "$dir_path"/* ... will not only move files but everything in "$dir_path". At least everything whose name does not start with a dot (hidden files). In bash you can change this with the option dotglob. But if the * expands nicely (matches everything but not too much for a command line) then you can use a shell for indirection: find . -type d -name "*dir*" ...


4

The rationale given in the POSIX specification is: The "-exec ... {} +" syntax adopted was a result of IEEE PASC Interpretation 1003.2 #210. It should be noted that this is an incompatible change to the ISO/IEC 9899:1999 standard. For example, the following command prints all files with a '-' after their name if they are regular files, and a '+' ...


0

Some example are here. You can use them.


0

IMO, grep -r works best. for instance, you want to search for the number 7546899 in a bunch of files: grep -r 7546899 it will show something like: <filename where is found the >:<something something>7546899<moretext>


1

find . -type f | while read file; do echo "${file##*.}"; done Has the advantage of bypassing all that tricky exec syntax that no one can ever remember. Also has the advantage of only creating one child process, instead of creating and destroying one for every found file. This is considerably faster than jimmij's version using exec # Preparation - 1000 ...


2

If you want to use shell parameter expansion then run some shell with exec: find . -type f -exec sh -c 'echo "${0##*.}"' {} \;


2

With zsh on a GNU system with uconv and recode: { echo '<html><head><meta charset="UTF-8"</head><body><pre>' users=(/var/cpanel/users/*(:t)) && find /home/$^users/public_html -type f -ctime -1 ! -iname '*cache*' -ls | uconv --from-callback escape-c -f utf8 -t utf8 | recode u8..html echo ...


2

Try: cd /var/cpanel/users && for i in * do find "/home/$i/public_html" -type f ! -iname '*cache*' -ctime -1 -ls done > /home/demo4/public_html/output.html Notes: Use >> instead of >, otherwise each iteration overwrites the output of the last. Or redirect the output of the whole loop, in which case you can use >. some find ...


0

You have to set IFS variable in bash: SAVEIFS=IFS IFS=$(echo -en "\n\b") ... YOURCODE .... IFS=$SAVEIFS But what does above code do? , it discard any space and meta char..


1

Before answering your answer, I highly recommend you reading two question: Why does my shell script choke on whitespace or other special characters? Security implications of forgetting to quote a variable in bash/POSIX shells For your question, you don't need a for loop, just find itself: find -type d If you want to do more things, just use -exec ...


1

If you're really just looking to echo the results of find, you can use the parameter -print (or just no additional parameter at all) to have find print a list of its results. If you want to delete the results, there's -delete (which can be combined with -print to get a list of the deleted files). If you want to do something else with/to the results, you ...


1

Something like the following works ... find . -type d | while read dir; do echo $dir; done . ./my dir Depending on what you're doing, you might be better using find's -print0 option and xargs -0. The code you've got takes the unquoted output from find and uses it as a list of words (split on whitespace) for for to iterate over.


1

Do not use for loop, use while instead: find . -type d -print0 | while read -d '' -r dir; do echo "$dir"; done Option print0 prints NULL character at the end of file/directory name (instead of newline) and read -d '' interprets it properly.


0

You find not matching result by option -L grep -iL shared.php .


4

Whatever you do, you'll need to invoke a shell to perform the redirection of the command output to a file whose location depends on the find result. find ./ *.md -not -path './/.git/*' -exec sh -c 'COMMAND "$0" > ~/wiki/newdirectory/"${0##*/}.cong"' {} \; Don't substitute {} inside the shell script. This isn't supported on all systems, and even where ...


1

If your find accepts -execdir, this should work find . -name '*.md' -not -path './/.git/*' -execdir COMMAND {} > ~/wiki/newdirectory/{}.cong \; Alternately find . -name '*.md' -not -path './/.git/*' -exec bash -c \ 'for f; do COMMAND "$f" > ~/wiki/newdirectory/"${f##*/}".cong; done' _ {} +


3

Try: find -type f ! -iname "*.JPG" -exec dirname {} \; | sort -u Notes; To complete the -exec command, a {} is needed to show where the filename should go and a semicolon is needed. Because the shell would eat a plain semicolon, we have to escape it so that it is passed on to find. -iname matches globs, not regular expressions. So, the final $ in ...


7

A -exec needs to be terminated with a ; or a +. The ; causes the command to execute once per found filename, whereas + causes the command to be executed once for all filenames. Here is a working example: find ! -iname "*.JPG" -exec dirname {} \; Some notable differences from your attempts: There must be a space between {} and \; The ; must be escaped, ...


3

The syntax: -exec [command] ... {} ... ; -exec [command] ... {} ... + Since ; is part of shell syntax, you need to escape it so that find sees it as an argument: find .. -exec dirname {} \; By the way, -iname doesn't use regular expressions - just use *.jpg without the $. It strikes me now that with GNU find we don't need to use dirname at all. ...


1

Here is an alternative way should rename happen to be missing: find 0[0-6][0-9] -name "*.jpg" -exec sh -c 'for i do echo mv "$i" "${i%g}eg"; done' sh {} +


3

In the first instance, * is expanded by the shell before it gets to rename (if it is expanded at all - I doubt anything matches {}/*), and if it isn't expanded, the command that is executed is rename with the three arguments -n, s/jpg/jpeg/ and some/path/*. That last argument is not the name of an existing file so rename does nothing. Without shell ...


0

You should not specify type d unless you want to rename only directories. To change extensions .jpg to .jpeg try find . -maxdepth 2 -mindepth 2 -name '*.jpg' -exec sh -c 'echo mv -- "$0" "${0%%.jpg}.jpeg"' {} \; Remove echo if you like what you see on the screen.


0

find | rename 's/\.jpg$/.jpeg/' or if you have oder files in the currunt directory find 0[0-9][0-9] | rename 's/\.jpg$/.jpeg/'


0

find | perl -ne 'print if(m!^\./(\d+)! and $1 > 126 and $1 <363)' ...possibly adding some of the good ideas presented in the other answers. Regex may need some tuning (eg: ^\./(\d+)\w*.po$)


3

Although it's not exactly the same thing as piping to xargs ls -al, the -ls flag of find itself might be enough for your and simplify the command a bit: find . ! -user username -mtime +365 -type f -ls > /tmp/list If you think a file is missing, look at what stat says about it. Keep in mind that -mtime is a condition concerning modification time. ...



Top 50 recent answers are included