다음 텍스트가 있고 모든 공백(따옴표 안의 공백 제외)을 개행 문자로 바꿔야 합니다.
입력하다
This is an example text with some spaces.
This should be 2nd line.
However the spaces between "quotes should not change".
last line
출력은 다음과 같아야 합니다.
This
is
an
example
text
with
some
spaces.
This
should
be
2nd
line.
However
the
spaces
between
"quotes should not change".
last
line
awk/sed/perl을 사용해 보았지만 따옴표를 제외하고 어디에 넣어야 할지 알 수 없었습니다.
인용된 텍스트는 한 줄을 초과하지 않습니다.
답변1
편집하다:내 솔루션은 완전히 과잉이었습니다. 내가 무슨 생각을 했는지 모르겠어요. 이 문제는 매우 간단한 정규식으로 해결할 수 있습니다. 바라보다해결책에 의해 제출 된조아오.
파이썬 shlex
라이브러리거의이것은 기본적으로 작동합니다. 다음은 예제 스크립트입니다:
#!/usr/bin/env python2
# -*- coding: ascii -*-
"""tokens.py"""
import sys
import shlex
with open(sys.argv[1], 'r') as textfile:
text = ''.join(textfile.readlines())
for token in shlex.split(text, posix=False):
print(token)
예를 들어 데이터가 파일에 있는 경우 data.txt
다음과 같이 실행할 수 있습니다.
python tokens.py data.txt
이것이 생성하는 출력은 다음과 같습니다.
이것 예 하나 예 텍스트 그리고 일부 공간. 이것 ~해야 한다 예 2위 철사. 하지만 이것 공간 ~ 사이 "인용문은 바뀌면 안 된다" . 마지막 철사
마침표는 별도의 줄에 표시됩니다. 이는 닫는 따옴표로 태그를 끝내기 때문입니다. 당신이 제시한 예에는 여러 줄의 문자열이나 이스케이프 문자가 필요하지 않은 것 같으므로 자신만의 작은 어휘분석기를 굴리는 것이 그리 어렵지 않을 수도 있습니다. 이것이 내가 생각해낸 것입니다:
#!/usr/bin/env python2
# -*- coding: ascii -*-
"""tokens.py"""
import sys
def tokenize(string):
"""Break a string into tokens using white-space as the only delimiter
while respecting double-quoted substrings and keeping the double-quote
characters in the resulting token."""
# List to store the resulting list of tokens
tokens = []
# List to store characters as we build the current token
token = []
# Flag to keep track of whether or not
# we're currently in a quoted substring
quoted = False
# Iterate through the string one character at a time
for character in string:
# If the character is a space then we either end the current
# token (if quoted is False) or add the space to the current
# token (if quoted is True)
if character == ' ':
if quoted:
token.append(character)
elif token:
tokens.append(''.join(token))
token = []
# A double-quote character is always added to the token
# It also toggles the 'quoted' flag
elif character == '"':
token.append(character)
if quoted:
quoted = False
else:
quoted = True
# All other characters are added to the token
else:
token.append(character)
# Whatever is left at the end becomes another token
if token:
tokens.append(''.join(token))
# Return the resulting list of strings
return(tokens)
if __name__=="__main__":
"""Read in text from a file and pring out the resulting tokens."""
with open(sys.argv[1], 'r') as textfile:
text = ''.join(textfile.readlines()).replace("\n", " ")
for token in tokenize(text):
print(token)
그러면 요청한 결과가 정확히 생성됩니다. Perl과 같은 다른 언어로 이 알고리즘을 쉽게 구현할 수 있습니다. 나는 단지 Python을 선호합니다.
답변2
GNU-grep을 사용하세요:
grep -Po '(".*?"|\S)+' file.txt
답변3
원본 텍스트에서 빈 줄을 제거할 수 있는 경우:
sed -r 's/("[^"]*"[^ ]?)/\n\1\n/g' input.txt |
sed -r '/^"/!s/\s{1,}/\n/g' |
sed '/^$/d'
원본 텍스트의 빈 줄을 유지해야 하는 경우:
sed -r 's/("[^"]*"[^ ]?)/###\n\1\n###/g' input.txt |
sed -r '/^"/!s/\s{1,}/\n/g' |
sed '/###/d'
입력하다(테스트가 더 복잡합니다.)
This is an "example text" with some spaces.
This should be 2nd line.
"However the spaces" between "quotes should not change".
"last line"
산출
This
is
an
"example text"
with
some
spaces.
This
should
be
2nd
line.
"However the spaces"
between
"quotes should not change".
"last line"