我需要帮助创建一些东西来处理数百个分割文本文件(001,002,003),它们都是相同的固定宽度格式,并指定由管道分隔的特定列中的每个字段。例如,原始数据可能如下所示:
123456789HA02HANKS PAUL 123 3rd Ave #2 NEW YORK NY10023198601042012235245
并在数据字典中定义为:
Field 1: SSN, start 1, end 9, length 9
Field 2: Name ID, start 10, end 11, length 2
Field 3: Transaction Number, start 12, end 13, length 2
Field 4: Last Name, start 14, end 29, length 16
Field 5: First Name, start 30, end 41, length 12
Field 6: Mailing Address, start 42, end 76, length 35
Field 7: City, start 77, end 92, length 16
Field 8: State, start 93, end 94, length 2
Field 9: Zip, start 95, end 99, length 5
Field 10: DOB, start 100, end 107, length 8
Field 11: Phone Number, start 108, end 117, length 10
我需要它看起来像:
123456789|HA|02|HANKS|PAUL|123 3rd Ave #2|NEW YORK|NY|10023|19860104|2012235245
我有一个C#控制台文件阅读器,它结合了多个文件,但我不知道如何将它们分成列。这是我的代码:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EmilysFileReader
{
public class Program
{
static void Main(string[] args)
{
Program prog = new Program();
Console.WriteLine("This program will attempt to combine all the files of a given directory.");
Console.WriteLine("Enter path to the directory:");
var path = Console.ReadLine();
string[] files = prog.CollectFiles(path);
Console.WriteLine("Name for the new file?");
string filename = Console.ReadLine();
prog.DoWork(Path.Combine(path, filename), files);
Console.WriteLine("Finished new file is " + Path.Combine(path, filename));
Console.WriteLine("Press enter to close.");
Console.ReadLine();
}
private void DoWork(string path, string[] files)
{
string filename = path + ".txt";
foreach (string file in files)
{
File.AppendAllText(filename, GetFileContent(file));
}
}
public string[] CollectFiles(string path)
{
string[] files = Directory.GetFiles(path);
Console.WriteLine("Found Files:");
foreach (string file in files)
{
Console.WriteLine(file);
}
return files;
}
public string GetFileContent(string file)
{
return File.ReadAllText(file);
}
}
}
我需要一种方法在C#,Java,SAS或SSMS中执行此操作。谁能指出我正确的方向?
答案 0 :(得分:0)
如果您说每行的格式都相同,那么您可以在Java中使用以下内容:
char delimiter = '|';
String text = "123456789HA02HANKS PAUL 123 3rd Ave #2 NEW YORK NY10023198601042012235245";
StringBuilder sb = new StringBuilder();
sb.append(text.substring(0, 9)).append(delimiter);
sb.append(text.substring(9, 11)).append(delimiter);
sb.append(text.substring(11, 13)).append(delimiter);
sb.append(text.substring(13, 25).trim()).append(delimiter);
sb.append(text.substring(25, 36).trim()).append(delimiter);
sb.append(text.substring(36, 55).trim()).append(delimiter);
sb.append(text.substring(55, 69).trim()).append(delimiter);
sb.append(text.substring(69, 71)).append(delimiter);
sb.append(text.substring(71, 76)).append(delimiter);
sb.append(text.substring(76, 84)).append(delimiter);
sb.append(text.substring(84));
System.out.println(sb);
当然,这并不是一种有效的方法,因为有些单词是用空格分隔的,有些是不是,有些可以有多个元素。希望你只需要运行一次。
编辑:更好的方法是在您知道元素结尾的索引处插入分隔符|,并修剪每个元素。
答案 1 :(得分:0)
这是SAS中的一个简单问题。要从源文件中读取修复长度值,您只需要一个简单的格式化输入语句。只需将所有内容都读为字符串。
while IFS=' ' read -r line; do
#echo ${line%*}
sed -e 's/\t.*$//' | xargs rm
done < $1
您可以使用PROC SQL into子句将名称/信息对列表构建到元数据文件中的宏变量中。
input field1 $10. field2 $2. .... ;
现在很容易构建一个简单的数据步骤,它将读取所有输入文件并写入新的分隔文件。您可以在输入文件名中使用单个通配符让SAS一次读取所有文件。
proc sql noprint ;
select catx(' ',field,cats('$',length,'.'))
into :varlist separated by ' '
from metadata
;
quit;
文件名中带有通配符的简单输入无法将文件名列表构建到数据集中,并使用该数据集来驱动数据步骤。
data _null_;
infile '/mypath/*.dat' truncover ;
input &varlist ;
file '/myoutpath/newfile.txt' dsd dlm='|' ;
put (_all_) (:);
run;