다음 구조의 텍스트 목록이 있습니다(각 항목의 모든 줄은 탭 공백으로 시작하고 줄 사이에 빈 줄이 없으며 항목 사이에 하나의 빈 줄이 있습니다).
292G.- La Ilíada (tomo I) ; Collection one (volume 3) ; Homer ; http://www.ataun.eus/BIBLIOTECAGRATUITA/Cl%C3%A1sicos%20en%20Espa%C3%B1ol/Homero/Iliada.pdf
- I have to download more ancient greek texts.
- Another note line.
293G.- El Ingenioso Hidalgo "Don Quijote" De La Mancha ; Collection one (volume 1) ; Miguel de Cervantes ; http://www.daemcopiapo.cl/Biblioteca/Archivos/7_6253.pdf
- Masterpiece.
294G.- Crimen y castigo ; Collection one (volume 4) ; Fiódor Dostoyevski ; http://www.ataun.eus/BIBLIOTECAGRATUITA/Cl%C3%A1sicos%20en%20Espa%C3%B1ol/Fedor%20Dostoiewski/Crimen%20y%20castigo.pdf
- Russian masterpiece.
295G.- La isla del tesoro ; Collection one (volume 2) ; Robert Louis Stevenson ; https://www.biblioteca.org.ar/libros/130864.pdf
- I read this one as a kid.
292G 위치에서 시작하여 100권이 넘는 컬렉션이 계속됩니다. 나는 이 100권을 권 번호(두 번째 필드에서 찾을 수 있음)별로 정렬하고 싶습니다. 예상되는 출력은 다음과 같습니다.
292G.- El Ingenioso Hidalgo "Don Quijote" De La Mancha ; Collection one (volume 1) ; Miguel de Cervantes ; http://www.daemcopiapo.cl/Biblioteca/Archivos/7_6253.pdf
- Masterpiece.
293G.- La isla del tesoro ; Collection one (volume 2) ; Robert Louis Stevenson ; https://www.biblioteca.org.ar/libros/130864.pdf
- I read this one as a kid.
294G.- La Ilíada (tomo I) ; Collection one (volume 3) ; Homer ; http://www.ataun.eus/BIBLIOTECAGRATUITA/Cl%C3%A1sicos%20en%20Espa%C3%B1ol/Homero/Iliada.pdf
- I have to download more ancient greek texts.
- Another note line.
295G.- Crimen y castigo ; Collection one (volume 4) ; Fiódor Dostoyevski ; http://www.ataun.eus/BIBLIOTECAGRATUITA/Cl%C3%A1sicos%20en%20Espa%C3%B1ol/Fedor%20Dostoiewski/Crimen%20y%20castigo.pdf
- Russian masterpiece.
"
헤더에는 , (
, )
, 와 같은 문자와 문자열이 포함될 수 있지만 포함 되지는 않습니다 ;
(구분자 역할만 함). sort
여기에 답이 있다고 생각 하지만 그것은 내 멍청한 능력을 넘어서는 것입니다.
답변1
명시적인 언어 요구 사항을 지정하지 않았으므로 이는 Python 3.8의 더러운 솔루션입니다. 다른 사람들이 더 나은 방법을 생각해낼 수 있다고 확신하지만 이것만으로도 충분합니다.
이 코드는 텍스트가 현재 디렉터리의 list.txt라는 파일에 있다고 가정하고 new-list.txt라는 새 파일을 생성합니다.
또한 "-La isla del tesoro"에서 누락된 공백을 처리하지 않습니다.
import re
booklist = []
bookcount = 0
entry = ''
line_numbers = []
# Find and return the volume number for a book
def get_volnum(book):
volstring = ''
volstring = re.search('\\(volume (\d+)\\)', book)
volnum = volstring.group(1)
return volnum
# Read file and put in doc variable
doc = open('list.txt', 'r').readlines()
# Group each book in a single string and append in a booklist
for line in doc:
# if line begins with three decimals followed by 'G.', put line in a new entry.
if re.match("(\d\d\d)G.*", line):
#read the line number and append to a list
line_numbers.append(line.split('G.')[0])
# Add previous entry to booklist (without the three decimals and G.)
if bookcount > 0:
booklist.append(entry.split('G.')[1])
entry = line
bookcount +=1
# If line begins with a '- ', concatenate the line into the current entry.
if line.startswith('- '):
entry += line
#Append last line
booklist.append(entry.split('G.')[1])
# Make a list (booktable) that contains [volnum, book]
booktable = []
[booktable.append([get_volnum(book), book]) for book in booklist]
# Sort that list by volnum (index 0 of each list item of booktable)
booktable.sort(key=lambda x: int(x[0]))
line_numbers.sort()
# Write result to file
f = open("new-list.txt", "w")
for b in booktable:
f.write(line_numbers.pop(0) + 'G.' + b[1])
f.write('\n')
f.close()
답변2
이것은 (세 번째 인수가 , 및 제목에 , 또는 가 포함 설정된문자열match()
된 GNU awk를 사용하면 정렬되지 않은 주변 섹션 내의 원래 위치에 정렬된 섹션을 출력합니다.gensub()
sorted_in
FPAT
;
(
)
(volume <N>)
$ cat tst.awk
BEGIN {
RS = ""
ORS = "\n\n"
FPAT = "[^;]*(\"[^\"]*\")*[^;]*"
tgtColl = "one"
begSeqNr = 292
maxSeqs = 100
}
match($2,/Collection (.*) \(volume ([0-9]+))/,a) {
coll = a[1]
volNr = a[2]
seqNr = $1+0
}
(coll == tgtColl) && (seqNr >= begSeqNr) && (++seqCnt <= maxSeqs) {
vols[volNr] = $0
next
}
{
prtVols()
print
}
END { prtVols() }
function prtVols( volNr, seqNr, vol) {
PROCINFO["sorted_in"] = "@ind_num_asc"
seqNr = begSeqNr
for (volNr in vols) {
vol = vols[volNr]
sub(/[0-9]+/,seqNr++,vol)
print vol
}
delete vols
}
예를 들어, 이 입력이 질문의 화창한 날 사례에서 수정되어 몇 가지 유용한 테스트 사례를 추가한다고 가정합니다.
$ cat file
100G.- some earlier collection ; Collection zero (volume 1) ; Robert Louis Stevenson ; https://www.biblioteca.org.ar/libros/130864.pdf
- TEST earlier collection ID
200G.- right collection, too early sequence number; Collection one (volume 6) ; Homer ; http://www.ataun.eus/BIBLIOTECAGRATUITA/Cl%C3%A1sicos%20en%20Espa%C3%B1ol/Homero/Iliada.pdf
- TEST earlier sequence number
292G.- La Ilíada ; Collection one (volume 3) ; Homer ; http://www.ataun.eus/BIBLIOTECAGRATUITA/Cl%C3%A1sicos%20en%20Espa%C3%B1ol/Homero/Iliada.pdf
- I have to download more ancient greek texts.
- Another note line.
293G.- El Quijote ; Collection one (volume 1) ; Miguel de Cervantes ; http://www.daemcopiapo.cl/Biblioteca/Archivos/7_6253.pdf
- Masterpiece.
294G.- Crimen y castigo ; Collection one (volume 4) ; Fiódor Dostoyevski ; http://www.ataun.eus/BIBLIOTECAGRATUITA/Cl%C3%A1sicos%20en%20Espa%C3%B1ol/Fedor%20Dostoiewski/Crimen%20y%20castigo.pdf
- Russian masterpiece.
295G.- "Kill Bill; Bury Him (volume 2)" ; Collection one (volume 5) ; Tarantino ; https://www.biblioteca.org.ar/libros/130864.pdf
- TEST quoted title with sparator chars and target string
296G.- La isla del tesoro ; Collection one (volume 2) ; Robert Louis Stevenson ; https://www.biblioteca.org.ar/libros/130864.pdf
- I read this one as a kid.
300G.- some later collection ; Collection twenty-three (volume 2) ; Robert Louis Stevenson ; https://www.biblioteca.org.ar/libros/130864.pdf
- TEST later collecion ID
다음과 같이 출력됩니다.
$ awk -f tst.awk file
100G.- some earlier collection ; Collection zero (volume 1) ; Robert Louis Stevenson ; https://www.biblioteca.org.ar/libros/130864.pdf
- TEST earlier collection ID
200G.- right collection, too early sequence number; Collection one (volume 6) ; Homer ; http://www.ataun.eus/BIBLIOTECAGRATUITA/Cl%C3%A1sicos%20en%20Espa%C3%B1ol/Homero/Iliada.pdf
- TEST earlier sequence number
292G.- El Quijote ; Collection one (volume 1) ; Miguel de Cervantes ; http://www.daemcopiapo.cl/Biblioteca/Archivos/7_6253.pdf
- Masterpiece.
293G.- La isla del tesoro ; Collection one (volume 2) ; Robert Louis Stevenson ; https://www.biblioteca.org.ar/libros/130864.pdf
- I read this one as a kid.
294G.- La Ilíada ; Collection one (volume 3) ; Homer ; http://www.ataun.eus/BIBLIOTECAGRATUITA/Cl%C3%A1sicos%20en%20Espa%C3%B1ol/Homero/Iliada.pdf
- I have to download more ancient greek texts.
- Another note line.
295G.- Crimen y castigo ; Collection one (volume 4) ; Fiódor Dostoyevski ; http://www.ataun.eus/BIBLIOTECAGRATUITA/Cl%C3%A1sicos%20en%20Espa%C3%B1ol/Fedor%20Dostoiewski/Crimen%20y%20castigo.pdf
- Russian masterpiece.
296G.- "Kill Bill; Bury Him (volume 2)" ; Collection one (volume 5) ; Tarantino ; https://www.biblioteca.org.ar/libros/130864.pdf
- TEST quoted title with sparator chars and target string
300G.- some later collection ; Collection twenty-three (volume 2) ; Robert Louis Stevenson ; https://www.biblioteca.org.ar/libros/130864.pdf
- TEST later collecion ID
필드 구분 기호이므로 ;
제목에 나타나는 모든 항목은 단독으로 Kill Bill";" Bury Him
또는 인용된 전체 제목의 일부로(위의 예에서와 같이) 큰따옴표 안에 있어야 하며, 제목에 다른 문자가 있거나 문자열 중 아무 것도 필요하지 않습니다. 특별한 취급.
one
이것은 매우 사소한 조정이며 실제로 모든 세트를 원하고 begSeqNr
다음 과 같습니다. for 에 대한 텍스트 없이 100개만, seqCnt
주변 세트/시퀀스를 인쇄하지 않으려면 독립형 print
명령문을 제거하면 됩니다.
답변3
통해 awk
그리고암소 비슷한 일종의 영양-특징(!)는 배열 순회를 정의합니다. 참고: 전체 파일이 한 번에 RAM에 저장되는데 "볼륨이 100개 이상"이라고 하셨으므로 파일이 그다지 크지 않다고 가정합니다.
아이디어는
- 빈 줄로 레코드 구분(탭이 없다고 가정하고 한 줄에 두 개의 줄 바꿈)
- 필드 구분 기호로 괄호를 사용합니다. 볼륨 번호를 인덱스 식별자로 사용하여 행을 배열에 넣습니다. 따라서 숫자를 결합해야합니다.
sub
- "볼륨 X" 색인을 기준으로 출력 정렬
- 정렬된 방식으로 각 항목의 번호를 바꾸십시오(293G 등).
스크립트:
BEGIN { RS="" ; ORS="\n\n" ; FS="[()]" }
{id=$2 ; sub(/volume /,"",id) ; vol[id]=$0}
END {PROCINFO["sorted_in"]="@ind_num_asc"
n=292
for ( id in vol ) { gsub(/^\t.../,"\t"n++,vol[id]) ; print vol[id] } }
허비하다
awk -f script inputfile
답변4
<infile awk -F';' -v RS= '
/Collection one/{ n=$2; gsub(/[^0-9]*/, "", n); sub(/[0-9]+/, 292+n-1) }
{ print sep $0; sep="\0" }' |sort -z |tr '\0' '\n'