다음 file1.txt가 있습니다. 내가 하고 싶은 것은 value1을 value7로 변환하여 한 줄에 출력하는 것입니다. 값은 "Start"와 "End"라는 단어 사이에서 검색됩니다. 레이블/값이 누락된 경우 출력에 "NA"가 표시됩니다.
아래에서 원하는 output.txt를 참조하세요.
간단히 말해서 Start와 End 사이의 값을 복사하여 한 줄에 출력하고 싶습니다. 값 레이블이 없으면 값에 NA가 표시됩니다. 그리고 file1.txt를 찾을 때까지 계속해서 다른 레코드의 값을(처음부터 끝까지) 검색합니다.
파일 1.txt
Start
label1 label2 label3 label4
value1 value2 value3 value4
label5
value5
label6 label7
value6 value7
End
Start
label1 label2 label4
valueA valueB valueD
label5
valueE
label6
valueF
End
Start
.
.
.
End
출력.txt
label1 label2 label3 label4 label5 label6 label7
value1 value2 value3 value4 value5 value6 value7
valueA valueB NA valueD valueE valueF NA
답변1
이 Python 스크립트는 원하는 작업을 수행해야 합니다.
#!/usr/bin/env python
# -*- encoding: ascii -*-
"""parse.py
Parses a custom-format data-file.
Processes the file first and then prints the results.
"""
import sys
# Read the data from the file
file = open(sys.argv[1], 'r')
# Initialize a dictionary to collect the values for each label
labels = {}
# Initialize a stack to keep track of block state
stack = []
# Initialize a counter to count the number of blocks
block = 0
# Process the file
line = file.readline()
while line:
# Remove white-space
line = line.strip()
# The stack should be empty when we start a new block
if line.lower() == "start":
if stack:
raise Exception("Invalid File Format: Bad Start")
else:
stack.append(line)
# Otherwise the bottom of the stack should be a "Start"
# When we reach the end of a block we empty the stack
# end increment the block counter
elif line.lower() == "end":
if stack[0].lower() != "start":
raise Exception("Invalid File Format: Bad End")
else:
block += 1
stack = []
# Other lines should come in consecutive label/value pairs
# i.e. a value row should follow a label row
elif line:
# If there are an odd number of data rows in the stack then
# the current row should be a value row - check that it matches
# the corresponding label row
if len(stack[1:])%2==1:
_labels = stack[-1].split()
_values = line.split()
# Verify that the label row and value row have the same number
# of columns
if len(_labels) == len(_values):
stack.append(line)
for label, value in zip(_labels, _values):
# Add new labels to the labels dictionary
if label not in labels:
labels[label] = {
"cols": len(label)
}
# Add the value for the current block
labels[label][block] = value
# Keep track of the longest value for each label
# so we can format the output later
if len(value) > labels[label]["cols"]:
labels[label]["cols"] = len(value)
else:
raise Exception("Invalid File Format: Label/Value Mismatch")
# If there are an even number of data rows in the stack then
# the current row should be a label row - append it to the stack
else:
stack.append(line)
# Read the next line
line = file.readline()
# Construct the header row
header = ""
for label in labels:
cols = labels[label]["cols"]
header += "{0: <{width}}".format(label, width=cols+1)
# Construct the data rows
rows = []
for i in range(0, block):
row = ""
for label in labels:
cols = labels[label]["cols"]
row += "{0: <{width}}".format(labels[label].get(i, "NA"), width=cols+1)
rows.append(row)
# Print the results
print(header)
for row in rows:
print(row)
다음과 같이 실행할 수 있습니다.
python parse.py file1.txt
샘플 데이터에 대해 다음 출력을 생성합니다.
label1 label2 label3 label4 label5 label6 label7
value1 value2 value3 value4 value5 value6 value7
valueA valueB NA valueD valueE valueF NA