What Does an Asterisk at The End of a Mv Command Do

What does an asterisk at the end of a mv command do

The shell expands the wildcard *. The mv command never sees the wildcard, only the result of the expansion.

The wildcard * expands to the list of files in the current directory in lexicographic order. If the last file is a directory, then all the preceding files (/source.filenafoo, /source/filenabar, /dest/dest, hello) are moved to that subdirectory. If the last file is not a directory, mv complains that “target a.png is not a directory” (or words to that effect).

See What does mv ./* without specifying destination do? for more detailed examples.

Did 'mv *' and now I can't find my files

There are a few possibilities here depending on what was in your current directory when you ran the command. But before that I want to cover what the asterisk does.

* (globbing)

In bash (and, to my knowledge, other shells), an asterisk performs a type of filename expansion called globbing.

This basically expands the argument into a number of arguments that match the expression. So if you have just a * you get all of the (non-hidden) files in the current directory as an argument. For *.mkv it would expand to the list of all files ending with the extension .mkv.

mv * (with two files)

The mv command requires multiple arguments, and is generally used with two, moving the file at the path denotes by the first argument (the source) to the path denoted by the second argument (the destination). Generally speaking, this will replace the a file at the destination if it is present with the source file. In this case, recovering the original destination file might still be possible but would require file recovery techniques (i.e. the same as if you had deleted the file with rm).

So if you only had two files in your directory (or two mkv files if you ran that command), you would have effectively removed one of the files.

However, given that it sounds like you cannot find the files at all I think something else happened.

mv * (with many files)

If you had more than two matching files in the directory, mv would attempt to move all of them into a directory denoted by the final argument.

From a test I just did, it looks like it will error out if the last path does not denote a directory and simply do nothing.

Given this, I think your files are probably fine and simply got moved into one of the sub-directories where your files were. I'm not 100% sure but I would assume it would be the last one alphabetically.

For example, if your directory looked like this (subdir is a directory while file*.mkv are files):

$ ls
subdir file1.mkv file2.mkv file3.mkv

And you ran mv *. I would expect you now see:

$ ls
subdir

In this case, your file are probably in subdir:

$ ls subdir/
file1.mkv file2.mkv file3.mkv

If you can't find any of the files, even looking in sub-directories, you may need to provide more context for what you were doing in order to fully figure out what happened. You might also want to search through your bash history (~/.bash_history) to see exactly what commands you ran.

Linux mv command with time adding spaces

Thanks. All it seems it was the encoding was incorrect the line endings were not set to unix. I develop on a windows machine and deploy to the server which messed up the line endings.

How to use the mv command in Python with subprocess

if you call subprocess that way:

subprocess.call(["mv", "/home/somedir/subdir/*", "somedir/"])

you're actually giving the argument /home/somedir/subdir/* to the mv command, with an actual * file. i.e. you're actually trying to move the * file.

subprocess.call("mv /home/somedir/subdir/* somedir/", shell=True)

it will use the shell that will expand the first argument.

Nota Bene: when using the shell=True argument you need to change your argument list into a string that will be given to the shell.

Hint: You can also use the os.rename() or shutil.move() functions, along with os.path.walk() or os.listdir() to move the files to destination in a more pythonic way.

How do I escape the wildcard/asterisk character in bash?

Quoting when setting $FOO is not enough. You need to quote the variable reference as well:

me$ FOO="BAR * BAR"
me$ echo "$FOO"
BAR * BAR

linux wildcard usage in cp and mv

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.

What does the * next to gdb address mean?

The asterisk before the address indicates an indirect jump. So the jump target is not 0x8049774, but the target is stored at the address 0x8049774.



Related Topics



Leave a reply



Submit