Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

linux wildcard usage in cp and mv

Tags:

linux

shell

cp

mv

I am composing a script to process 20 files. All of them located in different directories. I have partial file name.

  1. In log directory, File1_Date_time.err change to File1__Date_time_orig.err
  2. cd ../scripts/
  3. sh File.sh

File1 directory is /data/data1directory/Sample_File1/logs/File1_Data_time.err
File2 directory is /data/data2directory/Sample_File2/logs/File2_Data_time.err
.....

My script looks like this. (runrunrun.sh)

#!/bin/bash INPUT=$1 mv /data/*/Sample_*/logs/*_Data_time.err /data/*/Sample_*/logs/*_Data_time_orig.err cp /data/*/Sample_*/scripts/*.sh /data/*/Sample_*/scripts/*_orig.sh sh /data/*/Sample_*/scripts/*_orig.sh 

When running it, I tried.
./runrunrun.sh File1
. runrunrun.sh File1
sh runrunrun.sh File1

mv: cannot move /data/data1directory/Sample_File1/logs/File1_Data_time.err /data/*/Sample_*/logs/*_Data_time_orig.err: No such file or directory cp also got similar feedback

Am I doing it correct?

Thanks!

like image 534
TJ Wu Avatar asked Feb 29 '16 20:02

TJ Wu


People also ask

Can you use wildcards with mv?

Standard Wildcards (globbing patterns) Can be used by: Standard wildcards are used by nearly any command (including mv, cp, rm and many others). this can represent any single character.

How do you use wildcard in cp?

If you want to copy all files from your current directory to /var/tmp/ you can use this wildcard to represent all files. You can also use it to copy all like files. For example if you wanted to copy all txt files from your currect directory to /var/tmp/.

Can cp interpret wildcards?

mv , cp , etc. aren't passed the wildcards you're writing, if those wildcards have any valid expansions. Instead, they're passed literal filenames created by running those expansions.

Which is faster cp or mv in Linux?

Between drives, 'mv' should essentially amount to cp + rm (copy to destination, then delete from source). On the same filesystem, 'mv' doesn't actually copy the data, it just remaps the inode, so it is far faster than cp.


2 Answers

Let's talk about how wildcards work for a minute.

cp *.txt foo 

doesn't actually invoke cp with an argument *.txt, if any files matching that glob exist. Instead, it runs something like this:

cp a.txt b.txt c.txt foo 

Similarly, something like

mv *.txt *.old 

...can't possibly know what to do, because when it's invoked, what it sees is:

mv a.txt b.txt c.txt *.old 

or, worse, if you already have a file named z.old, it'll see:

mv a.txt b.txt c.txt z.old 

Thus, you need to use different tools. Consider:

# REPLACES: mv /data/*/Sample_*/logs/*_Data_time.err /data/*/Sample_*/logs/*_Data_time_orig.err for f in /data/*/Sample_*/logs/*_Data_time.err; do   mv "$f" "${f%_Data_time.err}_Data_time_orig.err" done  # REPLACES: cp /data/*/Sample_*/scripts/*.sh /data/*/Sample_*/scripts/*_orig.sh for f in /data/*/Sample_*/scripts/*.sh; do   cp "$f" "${f%.sh}_orig.sh" done  # REPLACES: sh /data/*/Sample_*/scripts/*_orig.sh for f in /data/*/Sample_*/scripts/*_orig.sh; do   if [[ -e "$f" ]]; then     # honor the script's shebang and let it choose an interpreter to use     "$f"   else     # script is not executable, assume POSIX sh (not bash, ksh, etc)     sh "$f"   fi done 

This uses a parameter expansion to strip off the tail end of the old name before adding the new name.

like image 79
Charles Duffy Avatar answered Sep 23 '22 00:09

Charles Duffy


The find command can be used quite concisely in simple cases where you want to perform operations on wildcard (or more complex) filename matches. The technique below can be committed to memory ... almost !

This works by letting the find command run another command on each filename it finds. You can dry-run this example using echo instead of/in front of mv .

If we wanted to move all files in the current directory with name beginning 'report', to another parallel directory called 'reports' :

find . -name "report*.*" -exec mv '{}' ../reports/ \; 

The wildcard string must be in quotes, the {} marking the filename that was 'found' must be in quotes, and the final semicolon must be escaped - all due to Bash/shell treatment of those characters.

Look at the man page for find for more uses: https://linux.die.net/man/1/find

like image 45
MikeW Avatar answered Sep 27 '22 00:09

MikeW