-1

I'm trying to run a text manipulation script using bash. For the script, I want to take a text file for input using the following syntax

./my_Script.sh < filename

Is it possible to take input from files this way? I tried putting

'>' test.txt

on the first line of the script to try to read the data but all that does is create a blank text file.

4

It depends on what you want to achieve:

If you want to process each line in the input file, you can do something like this:

#!/bin/bash
while read -r line; do
  echo "Next line: $line"
  # or something more useful.... :-)
done

You can then call this script as you described:

./script.sh < input_file.txt

If you want to pass the file name to other tools you can do so like this:

#!/bin/bash

other_tool "$1"

and call your script like this:

./script.sh input_file.txt
3

If you want to hardcode that input redirection, use the exec command:

exec < test.txt

then you can do

while IFS= read -r line; do
    echo "got: $line"
done
3

With

./script.sh <filename

you attach the standard input of the script as a whole to the file filename. This means that anything that reads from standard input in your script will read from the filename file, until the end of that file is reached.

For example, a script that you would invoke in the above way, that simply changes all characters to upper-case, could be written as

#!/bin/sh

tr 'a-z' 'A-Z'

Note that filename or <filename is not an argument of the script, but an instruction to the shell to set up the script's standard input to come from the file.

On the other hand, if you ran the script using

./scripts.sh filename

then the name of the file would be available as $1 in the script and you would have to refer to that name when reading from the file:

#!/bin/sh

tr 'a-z' 'A-Z' <"$1"

or,

#!/bin/sh

filename=$1

tr 'a-z' 'A-Z' <"$filename"

This would allow you to parse the same file several times, whereas reading the contents through the standard input of the script would only allow you to read the file once (unless you saved it to a temporary file in the script, using e.g. cat >tmpfilename, and then parsed that).

Giving the script filenames on the command line would also allow you to process any number of files in a loop:

#!/bin/sh

for pathname do
    # code that processes "$pathname"
done

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.