我有一个脚本可以处理来自慢速大容量存储器的大量小文件。
出于性能原因,我将文件读入变量,然后使用此变量进行所有处理。这允许我只读取一次文件。
这很有效,除非最后一行是空的,那么变量将比文件短一行,见下面的简化示例。
有没有办法将文件末尾的空行读取到变量?
$ rm -f /tmp/a ; for i in $(seq 3) ; do echo $i >> /tmp/a ; done
$ cat /tmp/a
1
2
3
$ wc -l /tmp/a
3 /tmp/a
$ a="$(cat /tmp/a)"
$ echo "$a"
1
2
3
$ echo "$a" | wc -l
3
$ rm -f /tmp/b ; for i in $(seq 3) ; do echo $i >> /tmp/b ; done
$ echo >> /tmp/b # ADD EXTRA EMPTY LINE TO THE END
$ cat /tmp/b
1
2
3
$ wc -l /tmp/b
4 /tmp/b
$ b="$(cat /tmp/b)"
$ echo "$b"
1
2
3
$ echo "$b" | wc -l
3
答案 0 :(得分:6)
$(command)
删除所有尾随换行符。来自bash man page:
命令替换允许输出命令来替换命令名称。有两种形式:
`command`
或
$(cat file)
Bash通过执行命令并使用命令的标准输出替换命令替换来执行扩展,删除任何尾随换行符。嵌入的换行不会被删除,但在分词时可能会被删除。命令替换
$(< file)
可以替换为等效但更快mapfile
。
使用$ mapfile b < /tmp/b
$ printf '%s' "${b[@]}"
1
2
3
$ printf '%s' "${b[@]}" | wc -l
4
在保留换行符的同时读取整个文件。它将每一行读入一个数组。
echo
避免printf '%s'
,这会增加额外的换行符。 printf -v
没有这样做,所以你得到了数组中的确切内容。
如果不需要数组,可以使用$ mapfile b < /tmp/b
$ printf -v b '%s' "${b[@]}"
$ printf '%s' "$b"
1
2
3
$ printf '%s' "$b" | wc -l
4
将其展平为单个字符串,同时保留换行符。
class temp {
private :
char * name;
public :
temp(char * temp_name){
strcpy(name,temp_name);
cout << "Created"<<name<<endl;
}
~temp(){
cout<< "Destoyed"<<name<<endl;
}
};
int main() {
class temp person1("Jack");
class temp haha("Katy");
return 0;
}
出于性能原因,我将文件读入变量,然后使用此变量进行所有处理。这允许我只读取一次文件。
这可能是过早优化。从磁盘读取文件后,操作系统会将其保留在缓存中。重新读取仍在缓存中的文件非常快。