0

This is my script:

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

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

4
  • Your example script doesn't have anything like the output given, and is full of syntax errors.
    – muru
    Feb 26, 2016 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, 2016 at 12:32
  • See askubuntu.com/help/formatting, and apply proper code formatting next time, not blockquotes.
    – muru
    Feb 26, 2016 at 12:38
  • Side note: wc outputs bytes in the last field, not chars Feb 26, 2016 at 13:16

3 Answers 3

3

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")"
fi
5
  • 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 ? Feb 26, 2016 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, 2016 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. Feb 26, 2016 at 14:08
  • @Serg Okay, that should have been a comment to the OP question then, not to a reply.
    – jlliagre
    Feb 26, 2016 at 14:19
  • I posted my own answer there, check it out when you have time Feb 26, 2016 at 15:10
1

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.

[edit]:
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
then
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" ]
then
  echo "line words chars:"
  wc "$input"
fi
4
  • could you please explain in detail what exactly that second command does
    – arvind
    Feb 26, 2016 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, 2016 at 12:45
  • @arvind see my edit :-)
    – Wayne_Yux
    Feb 26, 2016 at 12:56
  • @jlliagre you are right - I made a small edit to take care of this
    – Wayne_Yux
    Feb 26, 2016 at 12:56
1

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:
/etc/passwd
  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
/etc/passwd
  49   75 2575 /etc/passwd
$> echo 'Give me a file' ; read LINE; wc < "$LINE"                                             
Give me a file
/etc/passwd
  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
asdf
/bin/mksh: can't open asdf: No such file or directory

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .