Skip to main content
added 839 characters in body
Source Link
ilkkachu
  • 147.9k
  • 16
  • 268
  • 441

I would just go with Perl, and slurp the file inThe tablature you posted seems to do a single regex substitutionbe built on it. With the blocks consisting of the literal stringsix-character long pieces, xx\\-x---- (two letters ex, two backslashes), replaced withwhere x\x is either a fret number or a dash. Like so:

perl 123456123456123456
 -0777x-----x-----x----
|------------------|
|------------------|
|-0----------------|
|-2-----2-----2----|
|-------2----------|
|-------------0----|

If they're all with that spacing, you can just simply change the pieces to remove some dashes, without regard for other lines.

$ sed -peEe 's/-(^xx\\\\\n.){6}----/"x\\\n" x-\1/g; 6s/meg'\|/-|/2' < filetab
|-------| 
|-------|
|-0-----|
|-2-2-2-|
|---2---|
|-----0-|

^xx\\\\\n is simply a start of a line But if you have tabs written with different spacings in the same file, xxthen it gets much harder, two escaped backslashesas we'd need to recognize the spacing for each tab, and a newlinein general, that can't even be done from the first line. {6} demands the text(since it can be empty as in parenthesis to repeat six timesyour example. In)

The solutions I can come up with for the replacement part we have x, backslash, a newline,more general case involve decoding the whole tablature and then reprinting it and that string is "multiplied" by sixwon't fit in this answer.


Note that sed's (/mthis/,/that/ makessyntax processes blocks of lines where the first line matches ^/this/ match start of, the last line toomatches /that/, and the block contains all lines in between. /e--/,/--/,/--/,... makesis therefore nonsense, since there are more patterns than just the replacement a Perl expression insteadstart and end of just a stringblock.

To match a block that looks like a tablature, you'd need to match the |- and then have the block extend for six lines. In GNU sed, you could use /g^|-/,+6 makes a global replacement, replacing all occurrencesfor that.)

I would just go with Perl, and slurp the file in to do a single regex substitution on it. With the blocks consisting of the literal string xx\\ (two letters ex, two backslashes), replaced with x\:

perl -0777 -pe 's/(^xx\\\\\n){6}/"x\\\n" x 6/meg' < file

^xx\\\\\n is simply a start of a line, xx, two escaped backslashes, and a newline. {6} demands the text in parenthesis to repeat six times. In the replacement part we have x, backslash, a newline, and that string is "multiplied" by six. (/m makes ^ match start of line too, /e makes the replacement a Perl expression instead of just a string, and /g makes a global replacement, replacing all occurrences.)

The tablature you posted seems to be built on six-character long pieces, -x----, where x is either a fret number or a dash. Like so:

 123456123456123456
 -x-----x-----x----
|------------------|
|------------------|
|-0----------------|
|-2-----2-----2----|
|-------2----------|
|-------------0----|

If they're all with that spacing, you can just simply change the pieces to remove some dashes, without regard for other lines.

$ sed -Ee 's/-(.)----/-\1/g; s/\|/-|/2' < tab
|-------| 
|-------|
|-0-----|
|-2-2-2-|
|---2---|
|-----0-|

But if you have tabs written with different spacings in the same file, then it gets much harder, as we'd need to recognize the spacing for each tab, and in general, that can't even be done from the first line. (since it can be empty as in your example.)

The solutions I can come up with for the more general case involve decoding the whole tablature and then reprinting it and that won't fit in this answer.


Note that sed's /this/,/that/ syntax processes blocks of lines where the first line matches /this/, the last line matches /that/, and the block contains all lines in between. /--/,/--/,/--/,... is therefore nonsense, since there are more patterns than just the start and end of a block.

To match a block that looks like a tablature, you'd need to match the |- and then have the block extend for six lines. In GNU sed, you could use /^|-/,+6 for that.

Source Link
ilkkachu
  • 147.9k
  • 16
  • 268
  • 441

I would just go with Perl, and slurp the file in to do a single regex substitution on it. With the blocks consisting of the literal string xx\\ (two letters ex, two backslashes), replaced with x\:

perl -0777 -pe 's/(^xx\\\\\n){6}/"x\\\n" x 6/meg' < file

^xx\\\\\n is simply a start of a line, xx, two escaped backslashes, and a newline. {6} demands the text in parenthesis to repeat six times. In the replacement part we have x, backslash, a newline, and that string is "multiplied" by six. (/m makes ^ match start of line too, /e makes the replacement a Perl expression instead of just a string, and /g makes a global replacement, replacing all occurrences.)