使用 Bash 逐行读取并保留空间

当我使用“ cat test.file”时,它将显示

1
2
3
4

当我使用 Bash 文件时,

cat test.file |
while read data
do
echo "$data"
done

会显现出来的

1
2
3
4

如何使结果与原始测试文件一样?

99872 次浏览

read data will split the data by IFS, which is typically " \t\n". This will preserve the blanks for you:

var=$(cat test.file)
echo "$var"
IFS=''
cat test.file |
while read data
do
echo "$data"
done

I realize you might have simplified the example from something that really needed a pipeline, but before someone else says it:

IFS=''
while read data; do
echo "$data"
done < test.file

Alternatively, use a good file parsing tool, like AWK:

awk '{
# Do your stuff
print
}' file

Just to complement DigitalRoss's response.

For that case that you want to alter the IFS just for this command, you can use parenthesis. If you do, the value of IFS will be changed only inside the subshell. Like this:

echo '  word1
word2' |  ( IFS='' ; while read line ; do echo "$line" check ; done ; )

The output will be (keeping spaces):

  word1 check
word2 check

Actually, if you don't supply an argument to the "read" call, read will set a default variable called $REPLY which will preserve whitespace. So you can just do this:

$ cat test.file | while read; do echo "$REPLY"; done

Maybe IFS is the key point as others said. You need to add only IFS= between while and read.

cat test.file |
while IFS= read data
do echo "$data"
done

and do not forget quotations of $data, else echo will trim the spaces.

But as Joshua Davies mentioned, you would prefer to use the predefined variable $REPLY.