J.Carter J.Carter - 1 year ago 240
Linux Question

How to solve this ambiguous redirect error

I want to run a program (anchor) in all the .fa files in a directory, and append the output back into the input files (as next lines of original input content). For that I have tried:

for f in ./*.fa ; do ./anchor $f -d ./; done >> $f

and it gives the error:

bash: $f: ambiguous redirect

I understand bash is objecting to post the output content in the input file, but as I am recently migrating from windows system, there I'm doing it as:

for %F in ("*.fa") do anchor %F -d ./ >> %%F

which gives me the desired output.

Although this might seems strange to append output in input files, but how can I do that in shell?


ps. I also try to use $$ in output redirection, but it forms a separate output file with different name and the original input content are also not merged in it.

Answer Source

the most logical way of doing it is to redirect from inside the loop instead, but not directly (thanks 123 for the comment: file cannot be input and output as the same time, maybe here it could work since windows loop seems to work, but let's not take useless risks...)

for f in ./*.fa ; do ./anchor $f -d ./ > /tmp/something; cat /tmp/something >> $f; done 

BTW: I wouldn't dare trying to explain what your original code does, is f defined/when $f is evaluated (before or after entering the for loop).

My guess is that $f just not evaluated and considered as $f literally, which confuses bash.

At any rate, it's incorrect.

EDIT: the windows version

for %F in ("*.fa") do anchor %F -d ./ >> %%F

does the redirection inside the loop (unlike your unix attempt), and it's really surprising that it works because of windows file locking...

What could happen (not sure) is that windows doesn't try to append to the file before something is issued on standard output, and at that moment, the program has closed the file as input.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download