I felt like this with my code for the first 5 years that I was coding as well. My code now isn't pristine or perfect, but I'm consistently satisfied with the quality of my final products. Here's what I did to get to the point where I'm happy with my code:

1. Debug and refactor. Early on, I'd stumble through creating a script. It was usually write three lines, see if that worked, repeat. I didn't plan ahead enough, and by the end, my code was just layers of ideas tightly held together by a file name. This aggravated me, so after I'd get my scripts working, I'd completely rewrite them from scratch, making improvements where I saw them, simplifying code wherever I could.

I've learned more debugging (generally my own) code than I have from any book or teacher.

This was a lot of time spent, but eventually I could start seeing ahead and could make those changes in real-time as I was writing them. I'm not saying that I don't go back and refactor my code now, but when I do it's usually to fix things for speed or bugs, not for code cleanliness.

2. Plan ahead. I know some people that write out the entire shell of their program -- all of the functions and names and comments of what each function will do -- before ever writing the actual logic. I never had the patience for that, but you can still plan ahead.

Take a look at what you're trying to accomplish, and find the areas where you know you don't know what you're doing. Do a bit of research on those points. See what others have done, there's a really good chance you're not the first person to do those things. If you're still not sure, ask for help. The community is almost always willing to help.

3. Clarity over cleverness, always. I always take the road that will be more easily maintainable in the long run rather than the code that will work the fastest. (But, you know, if you can hit both at once, awesome.) I like breaking things down into simple bits. All of my functions are either only accomplishing one task, or are strings to those one-task functions put together to do something complex (but is still considered one task).

4. Learn, practice, learn, practice, repeat. Don't just stick with one language, branch out and see how other languages tackle similar problems. Take a look at code that you thin is better than yours and figure out why you think that. Take a look at code that's worse than yours and figure out why you think that. Write those things down and keep a list next to your monitor. Review them each time you sit down. Put them into practice. A lot.

5. Perspective. Take a look at your own work from 2-3 years ago and look at how far you've come. You've probably covered more distance than you think. Even if you're not 100% happy with where you're at, the progress will be reassuring.

6. Finally, stop worrying about it. Think of some people that are really good at what they do: professional athletes, professional plumbers, professional anything. When they're in the clutch moments, they're not stressing about how what they're doing looks, they're in "the zone," their mind lets go and instincts take over. Programmers develop those instincts too.

You're probably much better than you think, and you're only going to get better every time you program. :)