This is my script:

echo "Enter a file name:\c "
read input
if [ -f $input ]
echo "line words chars:\c "
'echo wc $input'

Output is as expected

lines words chars: 4 20 3 test

where test is a file name

but the problem is i don't want to output a file name

not only for this example I want to apply it for many such scripts

  • Your example script doesn't have anything like the output given, and is full of syntax errors. – muru Feb 26 '16 at 12:22
  • since if i insert ` reverse quotes it's taking it as Blockquote. So i inserted inverted commas in place of it in `echo wc $input' – arvind Feb 26 '16 at 12:32
  • See askubuntu.com/help/formatting, and apply proper code formatting next time, not blockquotes. – muru Feb 26 '16 at 12:38
  • Side note: wc outputs bytes in the last field, not chars – Sergiy Kolodyazhnyy Feb 26 '16 at 13:16

Here is how I would do it:

printf "Enter a file name: " 
read input 
if [ -f "$input" ] ; then 
    printf "line words chars: %s\n" "$(wc -lwm < "$input")"
  • Not saying the answer is bad, I actually upvoted, but i don't understand why write an elaborate script , when wc < filename already does the necessary job ? – Sergiy Kolodyazhnyy Feb 26 '16 at 13:16
  • @Serg wc < filename doesn't do the whole job, the file name is expected to be provided interactively. If what you are concerned with is the "$( ... )" construction, it can be avoided that way: printf "line words chars: "; wc < $input – jlliagre Feb 26 '16 at 13:38
  • Oh, no, this use of printf is how I'd do it myself. My whole point is that interactive usage is completely useless. OP probably has this as a homework or something. For practical purposes, you rarely see a script or command that does interactive use. Just look at most of the basic utilities - find , stat, wc, grep . If you call them, they won't ask "Please give me a file: ". It's expected that a file is specified on the command line. – Sergiy Kolodyazhnyy Feb 26 '16 at 14:08
  • @Serg Okay, that should have been a comment to the OP question then, not to a reply. – jlliagre Feb 26 '16 at 14:19
  • I posted my own answer there, check it out when you have time – Sergiy Kolodyazhnyy Feb 26 '16 at 15:10

In your case, I don't believe it is good to restrict the output to a certain length, because your wc output may have different lengths. However you could do this by using cut:

Change the last line of your script to

wc "$input" | cut -c 1-6

This will only output the first 6 characters.

I believe, you better use this:

wc "$input" | sed -e s/"$input"$//

This will remove the content of the $input variable (in your case the file name) from the output. This version ignores the output length and can deal with longer output strings as well.

Explanation of the second command:

wc "$input"   #-> wc command as used before
|             #-> redirect output of wc to the next command
sed -e        #-> call the program "sed" with the following expression
s/"$input"$// #-> replace everything between / 1 and 2 with everything between / 2 and 3
              #->in this case: replace filename with nothing. The second "$" represents the end of the line (so the filename has to be the last element of the line)

By the way, there are a few other errors in your script:

echo "Enter a file name:\c "  -> you don't need the \c
read input              
if [ -f $input ]              -> you should always quote variables
echo "line words chars:\c "
'echo wc $input'              -> you should not use echo and '' here, if you want to execute wc
                              -> you are missing a "fi"

so this code should work:

echo "Enter a file name:"
read input
if [ -f "$input" ]
  echo "line words chars:"
  wc "$input"
  • could you please explain in detail what exactly that second command does – arvind Feb 26 '16 at 11:02
  • You shouldn't use the useless final "g" in your last suggestion. Even if that would be an unlikely event, that would report bogus values for a file with a fully numerical name that happen to match wc output. – jlliagre Feb 26 '16 at 12:45
  • @arvind see my edit :-) – Wayne_Yux Feb 26 '16 at 12:56
  • @jlliagre you are right - I made a small edit to take care of this – Wayne_Yux Feb 26 '16 at 12:56

The key to this question is wc behavior with respect to a file given as argument to read its contents, and with respect to stdin stream.

When wc has a file as argument, it will print that argument along with the count

$>  wc < /etc/passwd 
  49   75 2575
$>  cat /etc/passwd | wc                                
     49      75    2575
$>  wc /etc/passwd                                               
  49   75 2575 /etc/passwd

You could always trim the output of wc FILENAME with tools like AWK, cut or grep, but that's not necessary. Speaking of AWK , one could do something like this with it:

$> awk 'BEGIN{ print "Enter filename:" ; getline ; system("wc <"$0)  }'        
Enter filename:
  49   75 2575

But typical shell script will look like this:

$> echo 'Give me a file' ; read LINE; echo $LINE | xargs wc                                    
Give me a file
  49   75 2575 /etc/passwd
$> echo 'Give me a file' ; read LINE; wc < "$LINE"                                             
Give me a file
  49   75 2575

By the way, there is no need for checking if a file exists. Your shell or wc already do that:

$> echo 'Give me a file' ; read LINE; wc < "$LINE"                                             
Give me a file
/bin/mksh: can't open asdf: No such file or directory

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.