In bash, I have a script that a uses while loop to copy files in a certain folder to various different directories. After each file is copied, I've written

mv $dir/$file $dir/_$file

using _ in the file's prefix to mark that it's been copied. ($dir is where the files are copied from.) At the end of the loop, the script lists the unmarked files to show which ones have not been copied.

I came across a small conflict where some files get copied more than once to different directories, but it cannot copy the file again because its name has been changed.

I was thinking of using if [ $file -eq $dir/_$file ] but no good. What's a simple way to check a directory for "_$file" given "$file"?

If there is a better method of doing all of this, that would be swell.


Given a file which is expanded to by $filename:

if [[ -f "dir/_${filename}" ]]; then
    echo "The prefixed copy exists."
    echo "The prefixed copy does not exist."
  • What's difference between using double and single set of brackets? if [[ -f "dir/_${filename}" ]] or if [ -f $dir/_$file ] – obidyne Feb 13 '18 at 22:53
  • 1
    bash's "extended test" construct, identified by double-square-bracket enclosure, is a superset of the older, more fragile single-bracket enclosure. It is designed to work around accidental errors and "do the right thing" for things which would be an error with test or [. See tldp.org/LDP/abs/html/testconstructs.html#DBLBRACKETS – DopeGhoti Feb 13 '18 at 22:56
  • so, the double-square-bracket is the safer method when it comes to testing? – obidyne Feb 13 '18 at 22:58
  • In short, yes. If you're using a bash script, there is no reason to ever not use extended test constructs in place of the older flavor. If you are aiming for portability to other shells (e. g. sh), though, then using the more brittle test or [ would be the way to go. – DopeGhoti Feb 13 '18 at 23:01

I am seeing the answers, but I've put my answer too. Maybe it's will be helpful for somebody.



if [ "$filename" = "$(basename $directory/_$filename|tr -d ^_)" ]
    echo "Prefix exists."
    echo "Prefix not exists."

I was able to figure it out, using this:

[ -f $dir/_$file ]


if [ -f $dir/_$file ]; then

to simply check the existence of a file with the particular prefix. Quite simple, I made it more difficult than needed.

Sometimes, I don't know whether or not to use quotation whenever referencing variables.


The test with -eq would fail as the arguments are not integers (-eq tests for arithmetic equivalence of two integers).

What you probably want to do is to check whether the underscored name is already taken by something else, not just a regular file.

You may do this with

if [ -e "$dir/_$file" ]; then
    printf 'The name "%s" already exists in directory %s\n' "_$file" "$dir"

You would need to double quote $dir/_$file as I have shown above, or as "$dir"/_"$file" (as long as both $dir and $file are quoted). This avoids word splitting on the value of the variables, which in turn avoids a runtime syntax error if one or both of them for some reason contained whitespace characters. It also avoids invoking filename generation (globbing) on the directory and file name.

I've used the -e test because I assume that you'd also like to know if there, for example, is a directory with the underscored name in the $dir directory.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.