How to POSIX-ly count the number of lines in a string variable?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
10
down vote

favorite
1












I know I can do this in Bash:



wc -l <<< "$string_variable"


Basically, everything I found involved <<< Bash operator.



But in POSIX shell, <<< is undefined, and I have been unable to find an alternative approach for hours. I am quite sure there is a simple solution to this, but unfortunately, I didn't find it so far.










share|improve this question

























    up vote
    10
    down vote

    favorite
    1












    I know I can do this in Bash:



    wc -l <<< "$string_variable"


    Basically, everything I found involved <<< Bash operator.



    But in POSIX shell, <<< is undefined, and I have been unable to find an alternative approach for hours. I am quite sure there is a simple solution to this, but unfortunately, I didn't find it so far.










    share|improve this question























      up vote
      10
      down vote

      favorite
      1









      up vote
      10
      down vote

      favorite
      1






      1





      I know I can do this in Bash:



      wc -l <<< "$string_variable"


      Basically, everything I found involved <<< Bash operator.



      But in POSIX shell, <<< is undefined, and I have been unable to find an alternative approach for hours. I am quite sure there is a simple solution to this, but unfortunately, I didn't find it so far.










      share|improve this question













      I know I can do this in Bash:



      wc -l <<< "$string_variable"


      Basically, everything I found involved <<< Bash operator.



      But in POSIX shell, <<< is undefined, and I have been unable to find an alternative approach for hours. I am quite sure there is a simple solution to this, but unfortunately, I didn't find it so far.







      shell-script variable string posix






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 20 at 6:40









      Vlastimil

      7,4031157132




      7,4031157132




















          3 Answers
          3






          active

          oldest

          votes

















          up vote
          10
          down vote



          accepted










          The simple answer is that wc -l <<< "$string_variable" is a ksh/bash/zsh shortcut for printf "%sn" "$string_variable" | wc -l.



          There are actually differences in the way <<< and a pipe work: <<< creates a temporary file that is passed as input to the command, whereas | creates a pipe. In bash and pdksh/mksh (but not in ksh93 or zsh), the command on right-hand side of the pipe runs in a subshell. But these differences don't matter in this particular case.



          Note that in terms of counting lines, this assumes that the variable is not empty and does not end with a newline. Not ending with a newline is the case when the variable is the result of a command substitution, so you'll get the right result in most cases, but you'll get 1 for the empty string.



          There are two differences between var=$(somecommand); wc -l <<<"$var" and somecommand | wc -l: using a command substitution and a temporary variable strips away blank lines at the end, forgets whether the last line of output ended in a newline or not (it always does if the command outputs a valid nonempty text file), and overcounts by one if the output is empty. If you want to both preserve the result and count lines, you can do it by appending some known text and stripping it off at the end:



          output=$(somecommand; echo .)
          line_count=$(($(printf "%sn" "$output" | wc -l) - 1))
          printf "The exact output is:n%s" "$output%."





          share|improve this answer


















          • 1




            @Inian Keeping wc -l is exactly equivalent to the original: <<<$foo adds a newline to the value of $foo (even if $foo was empty). I explain in my answer why this may not have been what was wanted, but it's what was asked.
            – Gilles
            Nov 20 at 7:20

















          up vote
          2
          down vote













          Not conforming to shell built-ins, using external utilities like grep and awk with POSIX compliant options,



          string_variable="one
          two
          three
          four"


          Doing with grep to match start of lines



          printf '%s' "$string_variable" | grep -c '^'
          4


          And with awk



          printf '%s' "$string_variable" | awk 'BEGIN count=0 NF count++ END print count '


          Note that some of the GNU tools, especially, GNU grep does not respect POSIXLY_CORRECT=1 option to run the POSIX version of the tool. In grep the only behavior affected by setting the variable will be the difference in processing of the order of the command line flags. From the documentation (GNU grep manual), it seems that




          POSIXLY_CORRECT



          If set, grep behaves as POSIX requires; otherwise, grep behaves more like other GNU programs. POSIX requires that options that follow file names must be treated as file names; by default, such options are permuted to the front of the operand list and are treated as options.




          See How to use POSIXLY_CORRECT in grep?






          share|improve this answer


















          • 2




            Surely wc -l is still viable here?
            – Michael Homer
            Nov 20 at 7:05










          • @MichaelHomer: From what I've observed, wc -l needs a proper newline delimited stream (having a trailing 'n` at the end to count properly). One cannot use a simple FIFO to use with printf, e.g. printf '%s' "$string_variable" | wc -l might not work as expected but <<< would because of the trailing n appended by the herestring
            – Inian
            Nov 20 at 7:14







          • 1




            That was what printf '%sn' was doing, before you took it out...
            – Michael Homer
            Nov 20 at 7:18

















          up vote
          0
          down vote













          The here-string <<< is pretty much a one-line version of the here-document <<. The former isn't a standard feature, but the latter is. You can use << too in this case. These should be equivalent:



          wc -l <<< "$somevar"

          wc -l << EOF
          $somevar
          EOF


          Though do note that both add an extra newline at the end of $somevar, e.g. this prints 6, even though the variable only has five lines :



          s=$'foonnnbarnn'
          wc -l <<< "$s"


          With printf, you could decide if you want the additional newline or not:



          printf "%sn" "$s" | wc -l # 6
          printf "%s" "$s" | wc -l # 5


          But then, do note that wc only counts complete lines (or the number of newline characters in the string). grep -c ^ should also count the final line fragment.



          s='foo'
          printf "%s" "$s" | wc -l # 0 !

          printf "%s" "$s" | grep -c ^ # 1



          (Of course you could also count the lines entirely in the shell by using the $var%... expansion to remove them one at a time in a loop...)






          share|improve this answer






















            Your Answer








            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "106"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            convertImagesToLinks: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













             

            draft saved


            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f482893%2fhow-to-posix-ly-count-the-number-of-lines-in-a-string-variable%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            3 Answers
            3






            active

            oldest

            votes








            3 Answers
            3






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            10
            down vote



            accepted










            The simple answer is that wc -l <<< "$string_variable" is a ksh/bash/zsh shortcut for printf "%sn" "$string_variable" | wc -l.



            There are actually differences in the way <<< and a pipe work: <<< creates a temporary file that is passed as input to the command, whereas | creates a pipe. In bash and pdksh/mksh (but not in ksh93 or zsh), the command on right-hand side of the pipe runs in a subshell. But these differences don't matter in this particular case.



            Note that in terms of counting lines, this assumes that the variable is not empty and does not end with a newline. Not ending with a newline is the case when the variable is the result of a command substitution, so you'll get the right result in most cases, but you'll get 1 for the empty string.



            There are two differences between var=$(somecommand); wc -l <<<"$var" and somecommand | wc -l: using a command substitution and a temporary variable strips away blank lines at the end, forgets whether the last line of output ended in a newline or not (it always does if the command outputs a valid nonempty text file), and overcounts by one if the output is empty. If you want to both preserve the result and count lines, you can do it by appending some known text and stripping it off at the end:



            output=$(somecommand; echo .)
            line_count=$(($(printf "%sn" "$output" | wc -l) - 1))
            printf "The exact output is:n%s" "$output%."





            share|improve this answer


















            • 1




              @Inian Keeping wc -l is exactly equivalent to the original: <<<$foo adds a newline to the value of $foo (even if $foo was empty). I explain in my answer why this may not have been what was wanted, but it's what was asked.
              – Gilles
              Nov 20 at 7:20














            up vote
            10
            down vote



            accepted










            The simple answer is that wc -l <<< "$string_variable" is a ksh/bash/zsh shortcut for printf "%sn" "$string_variable" | wc -l.



            There are actually differences in the way <<< and a pipe work: <<< creates a temporary file that is passed as input to the command, whereas | creates a pipe. In bash and pdksh/mksh (but not in ksh93 or zsh), the command on right-hand side of the pipe runs in a subshell. But these differences don't matter in this particular case.



            Note that in terms of counting lines, this assumes that the variable is not empty and does not end with a newline. Not ending with a newline is the case when the variable is the result of a command substitution, so you'll get the right result in most cases, but you'll get 1 for the empty string.



            There are two differences between var=$(somecommand); wc -l <<<"$var" and somecommand | wc -l: using a command substitution and a temporary variable strips away blank lines at the end, forgets whether the last line of output ended in a newline or not (it always does if the command outputs a valid nonempty text file), and overcounts by one if the output is empty. If you want to both preserve the result and count lines, you can do it by appending some known text and stripping it off at the end:



            output=$(somecommand; echo .)
            line_count=$(($(printf "%sn" "$output" | wc -l) - 1))
            printf "The exact output is:n%s" "$output%."





            share|improve this answer


















            • 1




              @Inian Keeping wc -l is exactly equivalent to the original: <<<$foo adds a newline to the value of $foo (even if $foo was empty). I explain in my answer why this may not have been what was wanted, but it's what was asked.
              – Gilles
              Nov 20 at 7:20












            up vote
            10
            down vote



            accepted







            up vote
            10
            down vote



            accepted






            The simple answer is that wc -l <<< "$string_variable" is a ksh/bash/zsh shortcut for printf "%sn" "$string_variable" | wc -l.



            There are actually differences in the way <<< and a pipe work: <<< creates a temporary file that is passed as input to the command, whereas | creates a pipe. In bash and pdksh/mksh (but not in ksh93 or zsh), the command on right-hand side of the pipe runs in a subshell. But these differences don't matter in this particular case.



            Note that in terms of counting lines, this assumes that the variable is not empty and does not end with a newline. Not ending with a newline is the case when the variable is the result of a command substitution, so you'll get the right result in most cases, but you'll get 1 for the empty string.



            There are two differences between var=$(somecommand); wc -l <<<"$var" and somecommand | wc -l: using a command substitution and a temporary variable strips away blank lines at the end, forgets whether the last line of output ended in a newline or not (it always does if the command outputs a valid nonempty text file), and overcounts by one if the output is empty. If you want to both preserve the result and count lines, you can do it by appending some known text and stripping it off at the end:



            output=$(somecommand; echo .)
            line_count=$(($(printf "%sn" "$output" | wc -l) - 1))
            printf "The exact output is:n%s" "$output%."





            share|improve this answer














            The simple answer is that wc -l <<< "$string_variable" is a ksh/bash/zsh shortcut for printf "%sn" "$string_variable" | wc -l.



            There are actually differences in the way <<< and a pipe work: <<< creates a temporary file that is passed as input to the command, whereas | creates a pipe. In bash and pdksh/mksh (but not in ksh93 or zsh), the command on right-hand side of the pipe runs in a subshell. But these differences don't matter in this particular case.



            Note that in terms of counting lines, this assumes that the variable is not empty and does not end with a newline. Not ending with a newline is the case when the variable is the result of a command substitution, so you'll get the right result in most cases, but you'll get 1 for the empty string.



            There are two differences between var=$(somecommand); wc -l <<<"$var" and somecommand | wc -l: using a command substitution and a temporary variable strips away blank lines at the end, forgets whether the last line of output ended in a newline or not (it always does if the command outputs a valid nonempty text file), and overcounts by one if the output is empty. If you want to both preserve the result and count lines, you can do it by appending some known text and stripping it off at the end:



            output=$(somecommand; echo .)
            line_count=$(($(printf "%sn" "$output" | wc -l) - 1))
            printf "The exact output is:n%s" "$output%."






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 20 at 10:46









            ilkkachu

            53.8k781146




            53.8k781146










            answered Nov 20 at 7:14









            Gilles

            522k12610401570




            522k12610401570







            • 1




              @Inian Keeping wc -l is exactly equivalent to the original: <<<$foo adds a newline to the value of $foo (even if $foo was empty). I explain in my answer why this may not have been what was wanted, but it's what was asked.
              – Gilles
              Nov 20 at 7:20












            • 1




              @Inian Keeping wc -l is exactly equivalent to the original: <<<$foo adds a newline to the value of $foo (even if $foo was empty). I explain in my answer why this may not have been what was wanted, but it's what was asked.
              – Gilles
              Nov 20 at 7:20







            1




            1




            @Inian Keeping wc -l is exactly equivalent to the original: <<<$foo adds a newline to the value of $foo (even if $foo was empty). I explain in my answer why this may not have been what was wanted, but it's what was asked.
            – Gilles
            Nov 20 at 7:20




            @Inian Keeping wc -l is exactly equivalent to the original: <<<$foo adds a newline to the value of $foo (even if $foo was empty). I explain in my answer why this may not have been what was wanted, but it's what was asked.
            – Gilles
            Nov 20 at 7:20












            up vote
            2
            down vote













            Not conforming to shell built-ins, using external utilities like grep and awk with POSIX compliant options,



            string_variable="one
            two
            three
            four"


            Doing with grep to match start of lines



            printf '%s' "$string_variable" | grep -c '^'
            4


            And with awk



            printf '%s' "$string_variable" | awk 'BEGIN count=0 NF count++ END print count '


            Note that some of the GNU tools, especially, GNU grep does not respect POSIXLY_CORRECT=1 option to run the POSIX version of the tool. In grep the only behavior affected by setting the variable will be the difference in processing of the order of the command line flags. From the documentation (GNU grep manual), it seems that




            POSIXLY_CORRECT



            If set, grep behaves as POSIX requires; otherwise, grep behaves more like other GNU programs. POSIX requires that options that follow file names must be treated as file names; by default, such options are permuted to the front of the operand list and are treated as options.




            See How to use POSIXLY_CORRECT in grep?






            share|improve this answer


















            • 2




              Surely wc -l is still viable here?
              – Michael Homer
              Nov 20 at 7:05










            • @MichaelHomer: From what I've observed, wc -l needs a proper newline delimited stream (having a trailing 'n` at the end to count properly). One cannot use a simple FIFO to use with printf, e.g. printf '%s' "$string_variable" | wc -l might not work as expected but <<< would because of the trailing n appended by the herestring
              – Inian
              Nov 20 at 7:14







            • 1




              That was what printf '%sn' was doing, before you took it out...
              – Michael Homer
              Nov 20 at 7:18














            up vote
            2
            down vote













            Not conforming to shell built-ins, using external utilities like grep and awk with POSIX compliant options,



            string_variable="one
            two
            three
            four"


            Doing with grep to match start of lines



            printf '%s' "$string_variable" | grep -c '^'
            4


            And with awk



            printf '%s' "$string_variable" | awk 'BEGIN count=0 NF count++ END print count '


            Note that some of the GNU tools, especially, GNU grep does not respect POSIXLY_CORRECT=1 option to run the POSIX version of the tool. In grep the only behavior affected by setting the variable will be the difference in processing of the order of the command line flags. From the documentation (GNU grep manual), it seems that




            POSIXLY_CORRECT



            If set, grep behaves as POSIX requires; otherwise, grep behaves more like other GNU programs. POSIX requires that options that follow file names must be treated as file names; by default, such options are permuted to the front of the operand list and are treated as options.




            See How to use POSIXLY_CORRECT in grep?






            share|improve this answer


















            • 2




              Surely wc -l is still viable here?
              – Michael Homer
              Nov 20 at 7:05










            • @MichaelHomer: From what I've observed, wc -l needs a proper newline delimited stream (having a trailing 'n` at the end to count properly). One cannot use a simple FIFO to use with printf, e.g. printf '%s' "$string_variable" | wc -l might not work as expected but <<< would because of the trailing n appended by the herestring
              – Inian
              Nov 20 at 7:14







            • 1




              That was what printf '%sn' was doing, before you took it out...
              – Michael Homer
              Nov 20 at 7:18












            up vote
            2
            down vote










            up vote
            2
            down vote









            Not conforming to shell built-ins, using external utilities like grep and awk with POSIX compliant options,



            string_variable="one
            two
            three
            four"


            Doing with grep to match start of lines



            printf '%s' "$string_variable" | grep -c '^'
            4


            And with awk



            printf '%s' "$string_variable" | awk 'BEGIN count=0 NF count++ END print count '


            Note that some of the GNU tools, especially, GNU grep does not respect POSIXLY_CORRECT=1 option to run the POSIX version of the tool. In grep the only behavior affected by setting the variable will be the difference in processing of the order of the command line flags. From the documentation (GNU grep manual), it seems that




            POSIXLY_CORRECT



            If set, grep behaves as POSIX requires; otherwise, grep behaves more like other GNU programs. POSIX requires that options that follow file names must be treated as file names; by default, such options are permuted to the front of the operand list and are treated as options.




            See How to use POSIXLY_CORRECT in grep?






            share|improve this answer














            Not conforming to shell built-ins, using external utilities like grep and awk with POSIX compliant options,



            string_variable="one
            two
            three
            four"


            Doing with grep to match start of lines



            printf '%s' "$string_variable" | grep -c '^'
            4


            And with awk



            printf '%s' "$string_variable" | awk 'BEGIN count=0 NF count++ END print count '


            Note that some of the GNU tools, especially, GNU grep does not respect POSIXLY_CORRECT=1 option to run the POSIX version of the tool. In grep the only behavior affected by setting the variable will be the difference in processing of the order of the command line flags. From the documentation (GNU grep manual), it seems that




            POSIXLY_CORRECT



            If set, grep behaves as POSIX requires; otherwise, grep behaves more like other GNU programs. POSIX requires that options that follow file names must be treated as file names; by default, such options are permuted to the front of the operand list and are treated as options.




            See How to use POSIXLY_CORRECT in grep?







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 20 at 7:06

























            answered Nov 20 at 6:56









            Inian

            3,785824




            3,785824







            • 2




              Surely wc -l is still viable here?
              – Michael Homer
              Nov 20 at 7:05










            • @MichaelHomer: From what I've observed, wc -l needs a proper newline delimited stream (having a trailing 'n` at the end to count properly). One cannot use a simple FIFO to use with printf, e.g. printf '%s' "$string_variable" | wc -l might not work as expected but <<< would because of the trailing n appended by the herestring
              – Inian
              Nov 20 at 7:14







            • 1




              That was what printf '%sn' was doing, before you took it out...
              – Michael Homer
              Nov 20 at 7:18












            • 2




              Surely wc -l is still viable here?
              – Michael Homer
              Nov 20 at 7:05










            • @MichaelHomer: From what I've observed, wc -l needs a proper newline delimited stream (having a trailing 'n` at the end to count properly). One cannot use a simple FIFO to use with printf, e.g. printf '%s' "$string_variable" | wc -l might not work as expected but <<< would because of the trailing n appended by the herestring
              – Inian
              Nov 20 at 7:14







            • 1




              That was what printf '%sn' was doing, before you took it out...
              – Michael Homer
              Nov 20 at 7:18







            2




            2




            Surely wc -l is still viable here?
            – Michael Homer
            Nov 20 at 7:05




            Surely wc -l is still viable here?
            – Michael Homer
            Nov 20 at 7:05












            @MichaelHomer: From what I've observed, wc -l needs a proper newline delimited stream (having a trailing 'n` at the end to count properly). One cannot use a simple FIFO to use with printf, e.g. printf '%s' "$string_variable" | wc -l might not work as expected but <<< would because of the trailing n appended by the herestring
            – Inian
            Nov 20 at 7:14





            @MichaelHomer: From what I've observed, wc -l needs a proper newline delimited stream (having a trailing 'n` at the end to count properly). One cannot use a simple FIFO to use with printf, e.g. printf '%s' "$string_variable" | wc -l might not work as expected but <<< would because of the trailing n appended by the herestring
            – Inian
            Nov 20 at 7:14





            1




            1




            That was what printf '%sn' was doing, before you took it out...
            – Michael Homer
            Nov 20 at 7:18




            That was what printf '%sn' was doing, before you took it out...
            – Michael Homer
            Nov 20 at 7:18










            up vote
            0
            down vote













            The here-string <<< is pretty much a one-line version of the here-document <<. The former isn't a standard feature, but the latter is. You can use << too in this case. These should be equivalent:



            wc -l <<< "$somevar"

            wc -l << EOF
            $somevar
            EOF


            Though do note that both add an extra newline at the end of $somevar, e.g. this prints 6, even though the variable only has five lines :



            s=$'foonnnbarnn'
            wc -l <<< "$s"


            With printf, you could decide if you want the additional newline or not:



            printf "%sn" "$s" | wc -l # 6
            printf "%s" "$s" | wc -l # 5


            But then, do note that wc only counts complete lines (or the number of newline characters in the string). grep -c ^ should also count the final line fragment.



            s='foo'
            printf "%s" "$s" | wc -l # 0 !

            printf "%s" "$s" | grep -c ^ # 1



            (Of course you could also count the lines entirely in the shell by using the $var%... expansion to remove them one at a time in a loop...)






            share|improve this answer


























              up vote
              0
              down vote













              The here-string <<< is pretty much a one-line version of the here-document <<. The former isn't a standard feature, but the latter is. You can use << too in this case. These should be equivalent:



              wc -l <<< "$somevar"

              wc -l << EOF
              $somevar
              EOF


              Though do note that both add an extra newline at the end of $somevar, e.g. this prints 6, even though the variable only has five lines :



              s=$'foonnnbarnn'
              wc -l <<< "$s"


              With printf, you could decide if you want the additional newline or not:



              printf "%sn" "$s" | wc -l # 6
              printf "%s" "$s" | wc -l # 5


              But then, do note that wc only counts complete lines (or the number of newline characters in the string). grep -c ^ should also count the final line fragment.



              s='foo'
              printf "%s" "$s" | wc -l # 0 !

              printf "%s" "$s" | grep -c ^ # 1



              (Of course you could also count the lines entirely in the shell by using the $var%... expansion to remove them one at a time in a loop...)






              share|improve this answer
























                up vote
                0
                down vote










                up vote
                0
                down vote









                The here-string <<< is pretty much a one-line version of the here-document <<. The former isn't a standard feature, but the latter is. You can use << too in this case. These should be equivalent:



                wc -l <<< "$somevar"

                wc -l << EOF
                $somevar
                EOF


                Though do note that both add an extra newline at the end of $somevar, e.g. this prints 6, even though the variable only has five lines :



                s=$'foonnnbarnn'
                wc -l <<< "$s"


                With printf, you could decide if you want the additional newline or not:



                printf "%sn" "$s" | wc -l # 6
                printf "%s" "$s" | wc -l # 5


                But then, do note that wc only counts complete lines (or the number of newline characters in the string). grep -c ^ should also count the final line fragment.



                s='foo'
                printf "%s" "$s" | wc -l # 0 !

                printf "%s" "$s" | grep -c ^ # 1



                (Of course you could also count the lines entirely in the shell by using the $var%... expansion to remove them one at a time in a loop...)






                share|improve this answer














                The here-string <<< is pretty much a one-line version of the here-document <<. The former isn't a standard feature, but the latter is. You can use << too in this case. These should be equivalent:



                wc -l <<< "$somevar"

                wc -l << EOF
                $somevar
                EOF


                Though do note that both add an extra newline at the end of $somevar, e.g. this prints 6, even though the variable only has five lines :



                s=$'foonnnbarnn'
                wc -l <<< "$s"


                With printf, you could decide if you want the additional newline or not:



                printf "%sn" "$s" | wc -l # 6
                printf "%s" "$s" | wc -l # 5


                But then, do note that wc only counts complete lines (or the number of newline characters in the string). grep -c ^ should also count the final line fragment.



                s='foo'
                printf "%s" "$s" | wc -l # 0 !

                printf "%s" "$s" | grep -c ^ # 1



                (Of course you could also count the lines entirely in the shell by using the $var%... expansion to remove them one at a time in a loop...)







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Nov 20 at 10:52

























                answered Nov 20 at 10:44









                ilkkachu

                53.8k781146




                53.8k781146



























                     

                    draft saved


                    draft discarded















































                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f482893%2fhow-to-posix-ly-count-the-number-of-lines-in-a-string-variable%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown






                    Popular posts from this blog

                    How to check contact read email or not when send email to Individual?

                    Displaying single band from multi-band raster using QGIS

                    How many registers does an x86_64 CPU actually have?