我正在尝试在ruby中创建一个脚本,该脚本读取文件夹中的文件,并将它们合并到一个单独的文件中。
这就是我想出来的
File.open('authorized_keys','a') do |mergedfile|
@files = Dir.glob('/home/<user>/ruby_script/*.keys')
for file in @files
text = File.open(file, 'r').read
text.each_line do |line|
mergedfile << line
end
end
end
我们的想法是,脚本将从github为我们的开发人员下载公钥文件,将它们合并到authorized_keys文件中,然后我们将scp到我们的云服务器。
我遇到的问题是,当生成authorized_key文件时,某些ssh键位于新行上,有些与其他行位于同一行。
我检查了下载的文件,每个密钥都在其自己的行上
如何确保每个键都在自己的行上?
由于
答案 0 :(得分:4)
在命令行中使用cat
可以更轻松地完成此操作。您可以轻松地将所有文件连接到一个文件中。这是来自命令行的man cat
:
The command:
cat file1 file2 > file3
will sequentially print the contents of file1 and file2 to the file file3,
truncating file3 if it already exists. See the manual page for your shell
(i.e., sh(1)) for more information on redirection.
您可以从目录中的文件数组轻松创建相应的命令,然后创建命令并通过反引号或%x
命令在子shell中执行它。
类似的东西:
require 'dir'
files = Dir['/path/to/files.*'].select{ |f| File.file?(f) }.join(' ')
`cat #{ files } > new_file`
您的原始代码可以更简洁地重写为:
File.open('authorized_keys','a') do |mergedfile|
Dir.glob('/home/<user>/ruby_script/*.keys').each do |file|
mergedfile.write(File.read(file))
end
end
代码的差异(和问题)是read
语句。这会将整个文件存入内存。如果该文件大于可用内存,程序将停止。厉害。有一些方法可以使用foreach
代替read
来解决这个问题,例如:
File.open('authorized_keys','a') do |mergedfile|
Dir.glob('/home/<user>/ruby_script/*.keys').each do |file|
File.foreach(file) do |li|
mergedfile.write(li)
end
end
end
答案 1 :(得分:2)
使用String#chomp
删除尾随换行符,然后添加换行符("\n"
或$/
):
"abc\n".chomp + "\n" # => "abc\n"
"abc".chomp + "\n" # => "abc\n"
mergedfile << line.chomp + "\n"
答案 2 :(得分:1)
文件中除最后一行之外的行肯定会以终结字符终止(否则,它们将不会被识别为行),因此您的问题是文件的结尾不一定是结束字符。为了确保这一点,改变行
text = File.open(file, 'r').read
到
text = File.open(file, 'r').read.sub(/#$/?\z/, $/)