3

I'm using the tr command to replace newlines with tabs from an output of another command, and I want to have multiple tabs to better align the output to a columnar format.

I see that tr has a [CHAR*REPEAT] option, where REPEAT could be a decimal or octal value, but I can't get it to work, e.g. the following simple line:

echo "1234" | tr ['2'] ['x'*3]

gives:

1x34

while I'm expecting:

1xxx34

What's the correct syntax to use?

  • Funny how you'd quote characters that don't need quoting (like 2 or x), and didn't those that do ([, ], *). tr '[2]abc' '[x*3][y*3] translate [, 2 and ] to x and a, b, c to y, it's another way to write tr '[2]abc' xxxyyy – Stéphane Chazelas Jul 16 at 8:56
  • @StéphaneChazelas that's just one of a dozen other attempts at getting the expected result, thinking that the problem was in the way I expresses that CHAR man pages talks about :-) – watery Jul 16 at 8:59
6

I'm afraid you are misunderstanding the meaning of the "repeat" option.

tr, as you correctly infer, is use to translate character sets. You call it with option

tr set1 set2

The idea is that both sets can contain multiple characters, i.e. you can say

tr 'abc' 'def'

and it will replace every a with a d, every b with an e and every c with an f. Now, you may want to replace multiple "input" characters with the same output character, say

tr 'abcdefghij' 'xxxxxxxxyz'

This will replace a to h with x, i with y and j with z. The "repeat" function is meant to make writing this less cumbersome, so the idea is that you can instead write

tr 'abcdefghij' '[x*8]yz'

as shorthand. So it is not meant for what you intend.

Instead, you can try sed

echo "1234" | sed 's/2/xxx/g'
1xxx34

This will substitute (s) all occurences (the trailing g) of 2 with xxx. Note that sed is also far more flexible than that (have a look at the questions tagged as for an overview of what is possible).

| improve this answer | |
  • Ha! [CHAR*REPEAT] REPEAT copies of CHAR, REPEAT octal if starting with 0 may I be forgiven for the misunderstanding? :-) Thanks, I'll definitely move to sed. – watery Jul 16 at 9:00
  • 2
    sed also has a y/abc/xyz/ to do tr's job though doesn't support the tr '[:lower:]' '[:upper:]' and co. Some have \U/\u as a non-standard extension though. – Stéphane Chazelas Jul 16 at 9:02
  • @watery I will certainly excuse you; had sufficient cases of misunderstandings myself ;). But yes, it would really seem like the best option to use sed for your use case ... – AdminBee Jul 16 at 9:05
  • ... or perhaps perl, which does have a repeat (string multiplication) operator (confusingly - for this example - the operator is x): echo "1234" | perl -pe 's/2/x x 3/ge' – steeldriver Jul 16 at 10:09

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.