Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Question:

Is it possible to access which number of a bash iteration is currently being processed?

Psuedo-Command

mv {1..5}.something.{1..5} $x1.$x2.something
  • Note: This is a logical representation; a non-working sample.

Pseudo-Output

mv 1.something.1 1.1.something
mv 1.something.2 1.2.something
...
mv n.something.m n.m.something
  • Where n and m are both the iteration of their respective brace expansion.

Explaination

I am familiar with loops such as:

for x in {1..10}; do echo -n "$x "; done

As you can see, bash is setting the iteration to $x. I wish to learn if it is possible, and how to access the variable which bash uses when I am not defining which variable to use. When bash is given a brace expansion without a variable to iterate over, it must do so [internally] somehow. I am hoping that this variable is accessible at run-time of the script.

Thanks to all the folks on #bash

share|improve this question
3  
The output you're showing is not the actual output. It's more like mv 1.something.1 1.something.2 1.something.3 1.something.4 1.something.5 2.something.1 2.something.2 2.something.3 2.something.4 2.something.5 3.something.1 3.something.2 3.something.3 3.something.4 3.something.5 4.something.1 4.something.2 4.something.3 4.something.4 4.something.5 5.something.1 5.something.2 5.something.3 5.something.4 5.something.5 ..something. In other words the brace expansion is expanded completely and not iterated over. You must use a for loop for iteration. –  Dennis Williamson Mar 28 '12 at 0:44
    
"As you can see, bash is setting the iteration to $a" - because you're using a for loop. –  Dennis Williamson Mar 28 '12 at 0:45
    
And, ultimately, the question is "Why?". What are you really trying to accomplish? –  Dennis Williamson Mar 28 '12 at 0:46
    
I've adjusted my question to [hopefully] clarify things. –  earthmeLon Mar 28 '12 at 1:37
    
Bash has some special variables/parameters, but nothing like Perl's $_. As I said before, "What are you really trying to accomplish?" See the echo example in l0b0's answer. There's no internal or implied variable. The expansion gets expanded all at once. The iteration is performed over the completed expansion by a for statement using a variable you supply. Bash has no concept of iterators in the sense that Python or Perl have. –  Dennis Williamson Mar 28 '12 at 10:57
add comment

3 Answers

up vote 4 down vote accepted

You are misunderstanding how brace expansion works. Please re-read Dennis Williamson's comment above.

You are thinking that when I write mv foo.{1,2,3} bar, that the shell is actually invoking the command multiple times, as if you'd typed:

mv foo.1 bar
mv foo.2 bar
mv foo.3 bar

If that were true, then your question would make sense: the shell is running multiple commands and so it has to keep a list.

But, that's not what's happening. Brace expansion expands one single argument then invokes the resulting command line one time. So for the above example, the shell sees that the argument foo.{1,2,3} contains brace expansion and it expands that argument into three arguments foo.1 foo.2 foo.3. Then it inserts that expansion into the command line in place of the braced argument, then it continues parsing the command line. When it's done the shell runs one command, which would look like this:

mv foo.1 foo.2 foo.3 bar

So yes, probably when the shell is expanding that braced argument it's keeping a list, but there's no way to access that list in the expansion of other arguments because the brace expansion is fully completed and all information about the expansion is used up and forgotten by the time the other arguments are being parsed.

The only way such an argument would be useful, anyway, would be if the shell is running multiple commands which it's not. To run multiple commands you have to use a real loop; brace expansion won't do that.

As for $_, that's a Perl construct that can be used in place of a loop variable (like x in your loop example), so it's not really relevant to brace expansion.

share|improve this answer
add comment

For mv specifically, you can simply use the -v flag to see what is currently being processed. As @DennisWilliamson pointed out, no variable is set for the brace expanded sequence - Writing echo {1..5} is equivalent to writing echo 1 2 3 4 5. Compare with echo "$foo" - There's no way after the fact to know which variable was echoed.

share|improve this answer
    
Thank you, but mv was a simple example of what I'm actually trying to accomplish. –  earthmeLon Apr 9 '12 at 6:52
add comment

why don't you use your own variable to count the iteration number and echo it. If you want to see what is happening on the execution , run it with -x option. Like bash -x will tell you where in ex. But without specifying what you are trying to achieve , it is difficult help.

share|improve this answer
    
Thank you for your suggestion. Because of my misunderstanding, I was hoping to 'shorcut' loops and use bash's iteration, but it seems that that is impossible. –  earthmeLon Mar 30 '12 at 3:04
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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