There are many examples of shell script-reading text files on the web, but they don't tell the whole story, only half of it. For example, read a text line from a testfile file in the following format:
Copy Code code as follows:
$ VI testfile
Ls-a-l/bin | Sort
Ls-a-l/bin | Sort | Wc
Ls-a-L | grep sh | Wc
Ls-a-L
Ls-a-L | Sort | Wc
One of the most common examples of line by line reading the contents of a file is:
Copy Code code as follows:
$ VI ReadFile
#!/bin/sh
Testfile=$1
While Read-r line
Todo
Echo $line
Done < $testfile
$ chmod +x ReadFile
$./readfile testfile
Ls-a-l/bin | Sort
Ls-a-l/bin | Sort | Wc
Ls-a-L | grep sh | Wc
Ls-a-L
Ls-a-L | Sort | Wc
The problem with this example is that after reading the lines of text, the text format changes and the contents of the original Testfile file are not exactly the same, and the space characters are automatically deleted. Why is that? Because IFS, if the shell script does not explicitly specify the IFS, the IFS will be used by default to separate spaces, tables, line, and so on, so the above text line in the extra space and line wrap are automatically indented.
What if you want to output the original format of the Testfile file, and print each line (as a whole) as it is? You need to specify the IFS variable to tell the shell to read in rows.
Copy Code code as follows:
$ VI ReadFile
#!/bin/sh
Ifs= ""
Testfile=$1
While Read-r line
Todo
Echo $line
Done < $testfile
$./readfile testfile
Ls-a-l/bin | Sort
Ls-a-l/bin | Sort | Wc
Ls-a-L | grep sh | Wc
Ls-a-L
Ls-a-L | Sort | Wc
The above two methods of output is not the same, what is the relationship between the first one is also beautiful some? Important, Vpsee yesterday wrote a simulation shell of the C program, and then wrote a shell script to test the C program, this script needs to read from the top of the testfile from the full line to the C program, if according to the above two methods will get two kinds of Different input formats are completely different in meaning:
Copy Code code as follows:
$./mypipe Ls-a-L | Sort | Wc
$./mypipe "Ls-a-l | Sort | WC "
Obviously what I want is the 2nd type of input, put "ls-a-l | Sort | WC "As a whole passed on to my mypipe to test whether my mypipe could correctly identify the various commands inside the string.
If you don't use IFS, there is another way to get the effect of the second method above:
Copy Code code as follows:
#!/bin/sh
Testfile=$1
x= ' wc-l $testfile |awk ' {print $} '
I=1
While [$i-le $x]
Todo
echo "' Head-$i $testfile | Tail-1 ' "
i= ' expr $i + 1 '
Done