Suppose I have multiple random .txt
files, and in the same directory I have nearly-identically-named files like filename.sql
and filename.txt
. How would I find those .sql
and their counterpart .txt
files without selecting any other .txt
files? (The intent here is to move them to a separate folder. There is a guaranteed 1:1 relationship between the relevant .sql
and .txt
files, meaning that I'm not worried about moving one of the random .txt
files mentioned initially.)
Very simple:
$ mv `ls *.sql|sed s/.sql$/.txt/g` dir
To see and understand how it works, how the shell expands the line before executing mv
, start the line with echo
:
$ ls
a.sql b.sql a.txt b.txt c.txt
$ echo mv `ls *.sql|sed s/.sql/.txt/g` dir
mv a.txt b.txt dir
Something more "robust" if the file names have spaces (generally not a good idea in Unix, but happens) or you have hundreds of files in the directory:
$ for f in *.sql; do mv "$(echo $f|sed s/.sql$/txt/)" dir; done
To move the .sql
files along with the corresponding .txt
files:
$ for f in *.sql; do mv "$f" "$(echo $f|sed s/.sql$/txt/)" dir; done
piokuc's answer works great, but if you get an argument list too long error (happens if you're moving a lot of files at once), this works as well:
ls *.sql | sed s/.sql/.txt/g | xargs -I% mv % /path/to/new/directory
Explanation:
.sql
extension..sql
with .txt
in the filename list (this doesn't rename the files, just operates on the piped input).xargs
xargs
is a program that runs other programs. We are going to run the mv
(move file) command through it.-I
option tells xargs
to run the mv
command individually for every single file name being passed by sed
.%
refers to actual object/filename being passed to xargs
, so upon each iteration this is going to be one of the substituted file names.%
: one is attached next to -I
, which tells xargs
to use the ampersand character as a token for a file name. The second occurrence is with mv
, where the actual (and by now changed) file name gets substituted for the token.Esentially, xargs
is saying, "For each one of the piped-in file names, run mv NEW_FILE_NAME.txt /path/to/new/directory
."
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With