LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   How to represent a lot of the same character? (http://www.linuxquestions.org/questions/programming-9/how-to-represent-a-lot-of-the-same-character-4175411321/)

dth4h 06-13-2012 08:46 PM

How to represent a lot of the same character?
 
Is there a way to represent a lot of the same character, without typing all of them?

I know that is confusing so here is an example

Instead of
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
Something like
w[47]


Here is two commands where that would be useful for me:
This removes 2 characters from the beginning of each line.
sed 's/^..//'

But what if I want to remove 50 characters from the beginning of each line?
This wouldn't look very good in code:
sed 's/^..................................................//'

And the other use would be echo

Tinkster 06-13-2012 10:08 PM

Something like this?
Code:

echo "..................................................ABCDEFG" | sed -r 's/^.{50}//'
ABCDEFG


danielbmartin 06-14-2012 09:35 AM

Quote:

Originally Posted by dth4h (Post 4702648)
Instead of
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
Something like
w[47]

You are looking for a simple kind of data compression.

Input file ...
Code:

ggggg
aaabcdefaa
bbbbcdecdebcd
ccxyzabcd
ttttttttttuttvwxyz

... this awk ...
Code:

awk -F "" \
  '{count=0; i=0; \
    do {count++ i++} while ($1==$i)}; \
  {printf "%s[%d]%s", $1, count-1, "\n"}' \
< $InFile

... produces this ...
Code:

g[5]
a[3]
b[4]
c[2]
t[10]

You may preserve the entire input line with this awk.
Code:

awk -F "" \
  '{count=0; i=0; \
    do {count++ i++} while ($1==$i)}; \
  {printf "%s[%d]%s%s", $1, count-1, substr($0,count), "\n"}' \
< $InFile

It produces this ...
Code:

g[5]
a[3]bcdefaa
b[4]cdecdebcd
c[2]xyzabcd
t[10]uttvwxyz

I am a beginner with awk and therefore invite knowledgeable LQers to polish my code (or replace it with something better).

Daniel B. Martin

David the H. 06-14-2012 06:04 PM

In regular expressions, you use {} to specify a numeric range.

(In sed this is an extended regex feature, so use "-r").

Code:

sed -r 's/^w{47}//'        #match exactly 47 "w"s
sed -r 's/^w{5,47}//'        #match between 5 and 47
sed -r 's/^w{5,}//'        #match at least 5 of them
sed -r 's/^w{,47)//'        #match up to 47 of them (including 0)

Note that like "*" and other similar forms, they are "greedy" and always grab the longest possible match.

Here are a few regular expressions tutorials:
http://mywiki.wooledge.org/RegularExpression
http://www.grymoire.com/Unix/Regular.html
http://www.regular-expressions.info/


For printing in the shell, use a combination of these:
brace expansion
printf

Here's a previous thread (started by the above danielmartin) concerning printing content patterns.

http://www.linuxquestions.org/questi...ontent-941877/

dth4h 06-14-2012 09:39 PM

Quote:

Originally Posted by Tinkster (Post 4702708)
Something like this?
Code:

echo "..................................................ABCDEFG" | sed -r 's/^.{50}//'
ABCDEFG


Thanks, Tinkster.

That is exactly what I was looking for, for the sed command.

Quote:

Originally Posted by David the H. (Post 4703536)
In regular expressions, you use {} to specify a numeric range.

(In sed this is an extended regex feature, so use "-r").

Code:

sed -r 's/^w{47}//'        #match exactly 47 "w"s
sed -r 's/^w{5,47}//'        #match between 5 and 47
sed -r 's/^w{5,}//'        #match at least 5 of them
sed -r 's/^w{,47)//'        #match up to 47 of them (including 0)

Note that like "*" and other similar forms, they are "greedy" and always grab the longest possible match.

Here are a few regular expressions tutorials:
http://mywiki.wooledge.org/RegularExpression
http://www.grymoire.com/Unix/Regular.html
http://www.regular-expressions.info/


For printing in the shell, use a combination of these:
brace expansion
printf

Here's a previous thread (started by the above danielmartin) concerning printing content patterns.

http://www.linuxquestions.org/questi...ontent-941877/

I still haven't found the answer for my question about echo, but it looks like the links David the H posted could have the answer.

Thanks everyone!

Nominal Animal 06-14-2012 10:19 PM

If you want to repeat string S for example 43 times using Bash:
Code:

$ S="Foo"
$ SP43="$( printf '%43s' '' )"
$ echo "${SP43// /$S}"
FooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFoo

If the number to repeat is a variable, say N :
Code:

$ S="Foo"
$ N=15
$ SPN="$( printf "%${N}s' '' )"
$ echo "${SPN// /$S}"
FooFooFooFooFooFooFooFooFooFooFooFooFooFooFoo

The trick is using the printf built-in (whenever you use echo, you can use printf, basically) to generate a string containing the desired number of spaces, then use the Bash string replacement to replace each space with the desired character or string.

If you need it more than once, I recommend using a simple Bash function:
Code:

# Repeat [-n] COUNT STRING...
Repeat () {
    if [ "$1" = "-n" ]; then
        local output='%s'
        shift 1
    else
        local output='%s\n'
    fi
    local pattern='%'$(( $1 ))'s'
    shift 1
    local temp="$(printf "$pattern" '')"
    printf "$output" "${temp// /$*}"
}

which has the added benefit of allowing an arithmetic expression for count (the first parameter), and one or more strings to be repeated:
Code:

$ Repeat 5 Foo
FooFooFooFooFoo
$ Repeat "2*3-1" Zaphod Beeblebrox
Zaphod BeeblebroxZaphod BeeblebroxZaphod BeeblebroxZaphod BeeblebroxZaphod Beeblebrox

If you want the same function to work both in Bash and other shells like dash, concatenate the right number of strings instead:
Code:

# Repeat [-n] COUNT STRING...
Repeat () {
    if [ "$1" = "-n" ]; then
        local output='%s'
        shift 1
    else
        local output='%s\n'
    fi

    local result=""
    local count=$(( $1 ))
    shift 1
    local part="$*"

    while [ $count -gt 0 ]; do
        [ $(( $count & 1 )) -gt 0 ] && result="$result$part"
        count=$((count / 2))
        part="$part$part"
    done

    printf "$output" "$result"
}

All Repeat variants above omit the trailing newline if the first parameter is -n .

dth4h 06-14-2012 10:34 PM

Quote:

Originally Posted by Nominal Animal (Post 4703681)
If you want to repeat string S for example 43 times using Bash:
Code:

$ S="Foo"
$ N=15
$ SPN="$( printf "%${N}s' '' )"
$ echo "${SPN// /$S}"
FooFooFooFooFooFooFooFooFooFooFooFooFooFooFoo


Thanks Nominal Animal! That is what I was looking for.

David the H. 06-15-2012 11:02 AM

Quote:

Originally Posted by dth4h (Post 4703653)
I still haven't found the answer for my question about echo, but it looks like the links David the H posted could have the answer.

Thanks everyone!

Yes, indeed, the last three links I gave provide multiple techniques, including, in a post I just made yesterday, the exact same technique NA posted above.


BTW, please don't quote entire posts verbatim when replying. You only need to quote previous replies when it wouldn't otherwise be clear who or what you are referring to. Even then, only include as much as absolutely necessary. Otherwise it just clutters up the thread.

pan64 06-15-2012 11:12 AM

what about the perl repetition operator:

PHP Code:

x
    The repetition operator
Returns a string consisting of the left operand repeated the number of times specified by the right operand.
    
In an array context, if the left operand is a list in parensit repeats the list.

        print 
'-' x 80;         # print row of dashes
        
print '-' x80;          # illegal, x80 is identifier

        
print "\t" ($tab/8), ' ' ($tab%8);    # tab over

        
@ones = (1x 80;               # an array of 80 1's
        
@ones = (5@ones;            # set all elements to 5

        
'blah' x 4;             # 'blahblahblahblah'
        
'*' x 3;                # '***'
        
10 x 5;                 # '1010101010' 


dth4h 06-15-2012 01:34 PM

Quote:

Originally Posted by David the H. (Post 4704137)
BTW, please don't quote entire posts verbatim when replying. You only need to quote previous replies when it wouldn't otherwise be clear who or what you are referring to. Even then, only include as much as absolutely necessary. Otherwise it just clutters up the thread.

Understood.

Quote:

Originally Posted by pan64 (Post 4704146)
what about the perl repetition operator:

I don't use perl, but if I ever do then this will be useful. Thanks

pan64 06-15-2012 01:43 PM

Quote:

Originally Posted by dth4h (Post 4704244)
I don't use perl, but if I ever do then this will be useful. Thanks

Don't forget: if you can do it with bash/awk/grep/sed/cut/tail/rev/sort/.... you can do it also with a single perl script.








__________________________________
Happy with solution ... mark as SOLVED
If someone helps you, or you approve of what's posted, click the "Add to Reputation" button, on the left of the post.

dth4h 06-15-2012 02:03 PM

Quote:

Originally Posted by pan64 (Post 4704250)
Don't forget: if you can do it with bash/awk/grep/sed/cut/tail/rev/sort/.... you can do it also with a single perl script.

If you can do it with bash/awk/grep/sed/cut/tail/rev/sort/ can you also do it with python? I am getting into learning python and I have read that python and perl can do a lot of the same things. So I am wondering if I can do all this with python or if I should also learn perl sometime in the future.

pan64 06-15-2012 02:28 PM

I found this link: http://stackoverflow.com/questions/4...rls-x-operator
I think python is similar to perl so yes, you can use python also (the syntax is not similar, but yes, both are really powerful and usable languages). Actually I know perl can do this, but I'm not really familiar with python.





__________________________________
Happy with solution ... mark as SOLVED
If someone helps you, or you approve of what's posted, click the "Add to Reputation" button, on the left of the post.

dth4h 06-15-2012 02:47 PM

Ahhh, sweet. Thanks.

Also, one more question. What is the technical term for what we have been discussing in this thread? Or in other words, what you can do with bash/awk/grep/sed/cut/tail/rev/sort/. Is it character manipulation?

Knowing this will help make my Google searches a lot more productive.

danielbmartin 06-15-2012 04:08 PM

Quote:

Originally Posted by dth4h (Post 4704305)
What is the technical term for what we have been discussing in this thread? Or in other words, what you can do with bash/awk/grep/sed/cut/tail/rev/sort/. Is it character manipulation?

I call it text processing.

Daniel B. Martin


All times are GMT -5. The time now is 04:33 AM.