How to pipe the results of 'find' to mv in Linux
find ./ -name '*article*' -exec mv {} ../backup \;
OR
find ./ -name '*article*' | xargs -I '{}' mv {} ../backup
Pipe 'find' command result list to move (mv) command – Terminal (zsh)
It's much easier to just do this:
- To your
.zshrc
file, add
then restart your shell.setopt extendedglob
- This enables you to use the
^
operator:mv ^A*(-.) Strings
(-.)
matches plain files or symlinks pointing to plain files. If you don't want the symlinks included, use(.)
instead.- See http://zsh.sourceforge.net/Doc/Release/Expansion.html#Filename-Generation for more info on the extended glob syntax.
⚠️ Note that extended glob syntax is similar to but not exactly the same as regular expression syntax!
How do you send the output of ls to mv?
One way is with backticks:
mv `ls *.boo` subdir
Edit: however, this is fragile and not recommended -- see @lhunath's asnwer for detailed explanations and recommendations.
BASH Linux - How to pass the result of find into a mv destination via echo
ShellCheck helpfully points out three issues with your command:
Your
-execdir
ignores everything before the-or
Your
\;
has to be a separate argument- Your
`..`
will expand once before find runs, not per file found.
Additionally,
- The {} in the
tr
is interpretted by find tr
arguments should not have[]
around them
Accounting for all this:
find . \( -name '*.pdf' -or -name '*.PDF' \) \
-execdir sh -c 'mv -v "$1" "$(echo "$1" | tr " " "_" | tr -d "{()},\!'\''" | tr "A-Z" "a-z" | sed "s/_-_/_/g")"' _ {} \;
Linux why can't I pipe find result to rm?
To expand on @Alex Gitelman's answer: yes, there's a difference between "standard input" and the command line.
When you type rm a.txt b.txt c.txt
, the files you list after rm
are known as arguments and are made available to rm through a special variable (called argv
internally). The standard input, on the other hand, looks to a Unix program like a file named stdin
. A program can read data from this "file" just as it would if it opened a regular file on disk and read from that.
rm
, like many other programs, takes its arguments from the command line but ignores standard input. You can pipe anything to it you like; it'll just throw that data away. That's where xargs
comes in handy. It reads lines on standard input and turns them into command-line arguments, so you can effectively pipe data to the command line of another program. It's a neat trick.
For example:
find . -name ".txt" | xargs rm
find . -name ".txt" | grep "foo" | xargs rm
Note that this will work incorrectly if there are any filenames containing newlines or spaces.
To deal with filenames containing newlines or spaces you should use instead:
find . -name ".txt" -print0 | xargs -0 rm
This will tell find
to terminate the results with a null character instead of a newline.
However, grep
won't work as before then. Instead use this:
find . -name ".txt" | grep "foo" | tr "\n" "\0" | xargs -0 rm
This time tr
is used to convert all newlines into null characters.
Command line: piping find results to rm
You are actually piping rm
's output to the input of find
. What you want is to use the output of find
as arguments to rm
:
find -type f -name '*.sql' -mtime +15 | xargs rm
xargs
is the command that "converts" its standard input into arguments of another program, or, as they more accurately put it on the man
page,
build and execute command lines from standard input
Note that if file names can contain whitespace characters, you should correct for that:
find -type f -name '*.sql' -mtime +15 -print0 | xargs -0 rm
But actually, find
has a shortcut for this: the -delete
option:
find -type f -name '*.sql' -mtime +15 -delete
Please be aware of the following warnings in man find
:
Warnings: Don't forget that the find command line is evaluated
as an expression, so putting -delete first will make find try to
delete everything below the starting points you specified. When
testing a find command line that you later intend to use with
-delete, you should explicitly specify -depth in order to avoid
later surprises. Because -delete implies -depth, you cannot
usefully use -prune and -delete together.
P.S. Note that piping directly to rm
isn't an option, because rm
doesn't expect filenames on standard input. What you are currently doing is piping them backwards.
How to pipe list of files returned by find command to cat to view all the files
Piping to another process (Although this WON'T accomplish what you said you are trying to do):
command1 | command2
This will send the output of command1 as the input of command2
-exec
on afind
(this will do what you are wanting to do -- but is specific tofind
)find . -name '*.foo' -exec cat {} \;
(Everything between
find
and-exec
are the find predicates you were already using.{}
will substitute the particular file you found into the command (cat {}
in this case); the\;
is to end the-exec
command.)send output of one process as command line arguments to another process
command2 `command1`
for example:
cat `find . -name '*.foo' -print`
(Note these are BACK-QUOTES not regular quotes (under the tilde ~ on my keyboard).)
This will send the output ofcommand1
intocommand2
as command line arguments. Note that file names containing spaces (newlines, etc) will be broken into separate arguments, though.
How to move or copy files listed by 'find' command in unix?
Adding to Eric Jablow's answer, here is a possible solution (it worked for me - linux mint 14 /nadia)
find /path/to/search/ -type f -name "glob-to-find-files" | xargs cp -t /target/path/
You can refer to "How can I use xargs to copy files that have spaces and quotes in their names?" as well.
Related Topics
Learning Kernel Hacking and Embedded Development at Home
Total Size of the Contents of All the Files in a Directory
Shell Script to Count Files, Then Remove Oldest Files
Importing a Cmake Project into Eclipse Cdt
In Linux, What Do All the Values in the "Top" Command Mean
Id_Rsa.Pub File Ssh Error: Invalid Format
Linux: Screen Desktop Video Capture Over Network, and Vnc Framerate
Checking for Installed Packages and If Not Found Install
How to Use Curl in a Shell Script
In Unix, How to Run 'Make' in a Directory Without Cd'Ing to That Directory First
Check Battery Level of Connected Bluetooth Device on Linux
How to Create a Script to Save and Restore Permissions
Display Only Files and Folders That Are Symbolic Links in Tcsh or Bash
Check If Environment Variable Is Already Set