`mv1 *.png` first expands the wildcard pattern `*.png` into the list of matching file names, then passes that list of file names to the function.

Then, inside the function `$1` means: take the first argument to the function, split it where it contains whitespace, and replace any of the whitespace-separated parts that contain wildcard characters and match at least one file name by the list of matching file names. Sounds complicated? It is, and this behavior is only occasionally useful and is often problematic. This splitting and matching behavior only occurs if `$1` occurs outside of double quotes, so the fix is easy: use double quotes. **[Always put double quotes around variable substitutions](https://unix.stackexchange.com/questions/131766/why-does-my-shell-script-choke-on-whitespace-or-other-special-characters)** unless you have a good reason not to.

For example, if the current directory contains the two files `A* algorithm.png` and `graph1.png`, then `mv1 *.png` passes `A* algorithm.png` as the first argument to the function and `graph1.png` as the second argument. Then `$1` is split into `A*` and `algorithm.png`. The pattern `A*` matches `A* algorithm.png`, and `algorithm.png` doesn't contain wildcard characters. So the function ends up running `mv` with the arguments `-n`, `A* algorithm.png`, `algorithm.png`, `targetdir` and `-v`. If you correct the function to
```
function mv1 { mv -n "$1" "targetdir" -v |wc -l ;}
```
then it will correctly move the first file.

To process _all_ the arguments, tell the shell to process all arguments and not just the first. You can use `"$@"` to mean the full list of arguments passed to the function.
```
function mv1 { mv -n "$@" "targetdir" -v |wc -l ;}
```
This is almost correct, but it still fails if a file name happens to begin with the character `-`, because `mv` will treat that argument as an option. Pass `--` to `mv` to tell it “no more options after this point”. This is a very common convention that most commands support.

```
function mv1 { mv -n -v -- "$@" "targetdir" |wc -l ;}
```

A remaining problem is that if `mv` fails, this function returns a success status, because the exit status of commands on the left-hand side of a pipe is ignored. In bash (or ksh), you can use `set -o pipefail` to make the pipeline fail. Note that setting this option may cause other code running in the same shell to fail, so you should set it locally in the function, which is possible since bash 4.4.
```
function mv1 {
  local -
  set -o pipefail
  mv -n -v -- "$@" "targetdir" | wc -l
}
```
In earlier versions, setting `pipefail` would be fragile, so it would be better to check `PIPESTATUS` explicitly instead.
```
function mv1 {
  mv -n -v -- "$@" "targetdir" | wc -l
  ((!${PIPESTATUS[0] && !${PIPESTATUS[1]}}))
}
```