5

文件 a.txt 末尾有两个空行

[yaxin@oishi tmp]$ cat -n a.txt 
     1  jhasdfj
     2  
     3  sdfjalskdf
     4  
     5  

我的脚本是:

[yaxin@oishi tmp]$ cat t.sh 
#!/bin/sh
a=`cat a.txt`
a_length=`echo "$a" | awk 'END {print NR}'`
echo "$a"
echo $a_length


[yaxin@oishi tmp]$ sh t.sh 
jhasdfj

sdfjalskdf
3

打开调试

[yaxin@oishi tmp]$ sh -x t.sh 
++ cat a.txt
+ a='jhasdfj

sdfjalskdf'
++ echo 'jhasdfj

sdfjalskdf'
++ awk 'END {print NR}'
+ a_length=3
+ echo 'jhasdfj

sdfjalskdf'
jhasdfj

sdfjalskdf
+ echo 3
3

cat 命令窃取文件末尾的空行。如何解决这个问题。

4

2 回答 2

3

cat命令不会窃取任何东西。这是命令替换。man bash说:

Bash 通过执行命令并用命令的标准输出替换命令替换来执行扩展,并删除任何尾随的换行符。嵌入的换行符不会被删除

如果要将命令的输出存储到变量中,可以&& echo .在命令之后添加、存储输出并删除最终的..

此外,要计算文件中的行数,规范的方法是运行wc -l

wc -l < a.txt
于 2013-08-14T08:29:28.003 回答
1

此处不需要 cat 命令,直接使用 awk 如下:

awk 'END {print NR}' a.txt

您的问题是将 cat 的输出存储在 shell 变量中。即使这样也会给出正确的输出(尽管是 UUOC 的情况):

cat a.txt | awk 'END {print NR}'

更新:当您尝试这样做时:

a=`cat a.txt`

要不然:

a=$(cat a.txt)

陷阱是进程替换,即像你有的反向引号内的命令或 $()带尾随换行符的命令。

您可以使用此技巧将尾随换行符存储在 shell 变量中:

a=`cat a.txt; echo ';'`
a="${a%;}"

测试变量值:

echo "$a"
printf "%q" "$a"

然后输出也将显示换行符:

jhasdfj

sdfjalskdf


$'jhasdfj\n\nsdfjalskdf\n\n\n'
于 2013-08-14T08:23:24.407 回答