How to repeat a dash (hyphen) in shell

前端 未结 7 799
北海茫月
北海茫月 2020-12-31 10:10

How can I repeat the character - n times in shell? I have read and tried this, but this does not work for -. It throws error invalid option

相关标签:
7条回答
  • 2020-12-31 10:30
    1. jot can do it, with no bashisms:

      jot -s '' -b - 100
      
    2. seq too, but not as well, it needs a tr:

      seq -s- 100 | tr -d '[0-9]'
      
    0 讨论(0)
  • 2020-12-31 10:36

    This throws an error:

    $ printf '-%.0s' {1..100}; echo ""
    bash: printf: -%: invalid option
    printf: usage: printf [-v var] format [arguments]
    

    This works fine under bash:

    $ printf -- '-%.0s' {1..100}; echo ""
    ----------------------------------------------------------------------------------------------------
    

    For other shells, try:

    printf -- '-%.0s' $(seq 100); echo ""
    

    The problem was the printf expects that - starts an option. As is common among Unix/POSIX utilities in this type of situation, -- signals to printf to expect no more options.

    0 讨论(0)
  • 2020-12-31 10:40

    Use a for loop and number range:

    for i in {1..10}; 
        do echo "-"; 
    done
    

    Or on a single line:

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

    which outputs ----------.

    EDIT: This was before your printf edit.

    0 讨论(0)
  • 2020-12-31 10:44

    This has been my goto for years... not AIX friendly though. Change the last character to change the repeating character which makes up the line

    printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' _
    
    0 讨论(0)
  • 2020-12-31 10:46

    I would recommend using a traditional for loop, as there is no need to spawn sub-processes or expand 100 arguments:

    N=100
    for((i = 0; i < $N; ++i)); do
      printf -
    done
    

    It is curious that printf -%s triggers "invalid option" but printf - does not. To perhaps be extra safe, you could do printf %s -.

    0 讨论(0)
  • 2020-12-31 10:47

    John1024's helpful answer provides a generic solution that shows how to disambiguate options from operands for all POSIX-like utilities.

    In the case at hand, the simplest solution is (works not only in bash, but also in ksh and zsh):

    printf '%.0s-' {1..100}
    

    Placing %.0s before the - avoids the issue of an initial - getting mistaken for an option.

    Slightly optimized:[1]

    printf '%.s-' {1..100}
    

    [1] %.0s is in practice the most portable form (to be fully portable, you must also avoid the brace expansion, {...}).
    %.s, the equivalent shorthand form, is supported by bash, ksh, and dash, but not zsh <= v5.2 - even though it is equally POSIX-compliant : "The precision [the part after .] shall take the form of a ( '.' ) followed by a decimal digit string; a null digit string is treated as zero."

    As a side note: The question originally contained a benign (in Bash) typo that sparked a debate: %0.s instead of %.0s: %0.s should effectively be the same as %.0s, and for that matter, the same as %.s and %0.0s (all effectively request: print a [minimum zero-width] field filled with a zero-length string), but in practice isn't: zsh <= v5.2 doesn't handle %0.s correctly (again, due to the .s part).
    Similarly, the GNU printf external-utility implementation (/usr/bin/printf), as of GNU coreutils v8.24, reports an error with %0.s, because it generally doesn't accept a field width of 0 with s: invalid conversion specification - this matters for lesser-known shells that don't provide printf as a builtin. Note that the BSD/OSX implementation does not have this problem.
    Both zsh's (<= v5.2) behavior with %.s and GNU /usr/bin/printf's behavior with %0s are deviations from the POSIX spec that smell like bugs.
    This question asks about zsh's behavior regarding %.s, and the bug has since been confirmed and reported as fixed via a post-v5.2 commit that has yet to be released as of this writing.

    0 讨论(0)
提交回复
热议问题