![30번째 탭 또는 88번째 공백부터 시작하여 파일의 마지막 3개 열의 형식을 지정하는 방법](https://linux55.com/image/138007/30%EB%B2%88%EC%A7%B8%20%ED%83%AD%20%EB%98%90%EB%8A%94%2088%EB%B2%88%EC%A7%B8%20%EA%B3%B5%EB%B0%B1%EB%B6%80%ED%84%B0%20%EC%8B%9C%EC%9E%91%ED%95%98%EC%97%AC%20%ED%8C%8C%EC%9D%BC%EC%9D%98%20%EB%A7%88%EC%A7%80%EB%A7%89%203%EA%B0%9C%20%EC%97%B4%EC%9D%98%20%ED%98%95%EC%8B%9D%EC%9D%84%20%EC%A7%80%EC%A0%95%ED%95%98%EB%8A%94%20%EB%B0%A9%EB%B2%95.png)
우분투 16.04 GNU bash, 버전 4.4.0
1,264,524줄의 우편번호가 포함된 이 텍스트 파일의 형식을 지정하고 싶습니다.
#!/bin/bash
wget http://download.geonames.org/export/zip/allCountries.zip
unzip allCountries.zip
mv -f allCountries.txt .allCountries.txt
rm -f allCountries.zip
이것은 파일의 포맷되지 않은 부분입니다.
AD AD100 Canillo 42.5833 1.6667 6
AD AD200 Encamp 42.5333 1.6333 6
AD AD300 Ordino 42.6 1.55 6
AD AD400 La Massana 42.5667 1.4833 6
AD AD500 Andorra la Vella 42.5 1.5 6
AD AD600 Sant Julià de Lòria 42.4667 1.5 6
AD AD700 Escaldes-Engordany 42.5 1.5667 6
AR 3636 POZO CERCADO (EL CHORRO (F), DPTO. RIVADAVIA (S)) Salta A -23.4933 -61.9267 3
AR 4123 LAS SALADAS Salta A -25.7833 -64.5 4
AR 4126 BARADERO Salta A -26.0833 -65.263 3
AR 4126 EL CUIBAL Salta A -26.0833 -65.263 3
AR 4126 LA ASUNCION Salta A -26.0833 -65.263 3
AR 4126 MIRAFLORES (TALA, DPTO. CANDELARIA) Salta A -26.0833 -65.263 3
AR 4141 TOLOMBON Salta A -26.2 -65.9167 4
AR 4141 QUISCA GRANDE Salta A -26.4367 -65.97 3
AR 4141 LA CIENEGUITA Salta A -26.4367 -65.97 3
AR 4141 MACHO RASTROJO Salta A -26.4367 -65.97 3
AR 4190 ROSARIO DE LA FRONTERA Salta A -25.8 -64.9667 4
AR 4190 OVANDO Salta A -25.8 -65.1 4
AR 4190 SAN ESTEBAN Salta A -25.8 -65.0333 3
AR 4190 LA BANDA (R. DE LA FRONTERA, DPTO. ROSARIO DE LA FRONTERA) Salta A -25.8 -65.0333 3
AR 4190 LA MATILDE Salta A -25.8 -65.0333 3
AR 4190 LAS PIEDRITAS Salta A -25.8 -65.0333 3
AR 4190 LOS POCITOS Salta A -25.8 -65.0333 3
AR 4190 OJO DE AGUA (ROSARIO DE LA FRONTERA, DPTO. R.DE LA FRONTERA) Salta A -25.8 -65.0333 3
AR 4190 POTRERILLO (R. DE LA FRONTERA, DPTO. ROSARIO DE LA FRONTERA) Salta A -25.8 -65.0333 3
최종 결과는 다음과 같습니다.
AD AD100 Canillo 42.5833 1.6667 6
AD AD200 Encamp 42.5333 1.6333 6
AD AD300 Ordino 42.6 1.56 6
AD AD400 La Massana 42.5667 1.4833 6
AD AD500 Andorra la Vella 42.5 1.6 6
AD AD600 Sant Julià de Lòria 42.4667 1.5 6
AD AD700 Escaldes-Engordany 42.5 1.5667 6
AR 3636 POZO CERCADO (EL CHORRO (F), DPTO. RIVADAVIA (S)) Salta A -23.4933 -61.9267 3
AR 4123 LAS SALADAS Salta A -25.7833 -64.5 4
AR 4126 BARADERO Salta A -26.0833 -65.263 3
AR 4126 EL CUIBAL Salta A -26.0833 -65.263 3
AR 4126 LA ASUNCION Salta A -26.0833 -65.263 3
AR 4126 MIRAFLORES (TALA, DPTO. CANDELARIA) Salta A -26.0833 -65.263 3
AR 4141 TOLOMBON Salta A -26.2 -65.9167 4
AR 4190 OJO DE AGUA (ROSARIO DE LA FRONTERA, DPTO. R.DE LA FRONTERA) Salta A -25.8 -65.0333 3
AR 4190 POTRERILLO (R. DE LA FRONTERA, DPTO. ROSARIO DE LA FRONTERA) Salta A -25.8 -65.0333 3
따라서 3번째 열부터 마지막 열까지 왼쪽은 30번째 탭, 즉 88번째 스페이스부터 시작해야 합니다. 마지막 3개 열의 첫 번째 문자는 12개의 공백만큼 떨어져 있습니다.
각 행에는 데이터가 있으므로 마지막 3개 열을 다른 파일로 잘라내려고 했습니다. 그런 다음 원본 파일에서 모든 공백을 제거한 다음 열 형식으로 지정해 보았습니다. 세 번째 열은 나에게 문제를 일으키고 있습니다.
awk 'BEGIN{ OFS="\t"}{ print $1, $2, NR }' .allCountries.txt
AT 4873 Pehigen 34069
AT 4873 Hofberg 34070
AT 4873 Wiederhals 34071
AT 4873 Oberedt 34072
AT 4873 Oberegg 34073
AT 4873 Raitenberg 34074
AT 4873 Redltal 34075
AT 4873 Friedhalbing 34076
AT 4873 Unterhaselbach 34077
AT 4873 Redltal 34078
AT 4873 Erkaburgen 34079
AT 4873 Mayrhof 34080
AT 4873 Erdpries 34081
AT 4873 Grünbergsiedlung 34082
AT 4873 Brunnhölzl 34083
AT 4873 Seibrigen 34084
AT 4873 Kinast 34085
AT 4873 Stöckert 34086
AT 4873 Frankenburg 34087
AT 4873 Fischeredt 34088
AT 4873 Marigen 34089
AT 4873 Oberhaselbach 34090
AT 4873 Ottokönigen 34091
AT 4873 Fischigen 34092
AT 4873 Endriegl 34093
어떤 도움이라도 좋을 것입니다.
답변1
이것이 가능할 것 같습니다. 간단한 단일 라이너로서 awk
1.2m 라인 파일에 대해 매우 빠르게 실행되어야 합니다. 귀하의 예를 기반으로 130만 줄의 더미 파일을 생성함으로써 4GB RAM 및 GNU Awk 4.0.2를 갖춘 기본 CentOS 7 VM에서 24초 만에 완료되는 것을 확인했습니다.
StackExchange에서 정확한 응답을 얻으려면 샘플 출력과 함께 샘플 입력을 Pastebin에 게시할 수 있습니다.
$ awk '{printf "%s %-6s%-81s%-12s%-12s%s\n",$1,$2,gensub(/[0-9.-]* +[0-9.-]* +[0-9]$/,"","g",substr($0,10)),$(NF-2),$(NF-1),$NF}' inp | head
AD AD100 Canillo 42.5833 1.6667 6
AD AD200 Encamp 42.5333 1.6333 6
AD AD300 Ordino 42.6 1.55 6
AD AD400 La Massana 42.5667 1.4833 6
AD AD500 Andorra la Vella 42.5 1.5 6
AD AD600 Sant Julià de Lòria 42.4667 1.5 6
AD AD700 Escaldes-Engordany 42.5 1.5667 6
AR 3636 POZO CERCADO (EL CHORRO (F), DPTO. RIVADAVIA (S)) Salta A -23.4933 -61.9267 3
AR 4123 LAS SALADAS Salta A -25.7833 -64.5 4
AR 4126 BARADERO Salta A -26.0833 -65.263 3
$
답변2
다음 스크립트를 사용하여 원하는 것을 달성할 수 있었지만 100만 개 이상의 행에서 얼마나 잘 작동할지는 잘 모르겠습니다.
#!/usr/local/bin/bash
tmp_dir="$(mktemp -d -t 'text.XXXXX' || mktemp -d 2>/dev/null)"
input=./input
output=./output
tmp_input1=${tmp_dir}/temp_input1.txt
tmp_input2=${tmp_dir}/temp_input2.txt
col1="${tmp_dir}/col1.txt"
col2="${tmp_dir}/col2.txt"
col3="${tmp_dir}/col3.txt"
col4="${tmp_dir}/col4.txt"
col5="${tmp_dir}/col5.txt"
col6="${tmp_dir}/col6.txt"
tr -s ' ' <"$input" > "$tmp_input1"
awk '{print $1}' "$tmp_input1" > "$col1"
awk '!($1="")' "$tmp_input1" > "$tmp_input2"
awk '{print $1}' "$tmp_input2" > "$col2"
awk '!($1="")' "$tmp_input2" > "$tmp_input1"
awk '{print $NF}' "$tmp_input1" > "$col6"
awk '!($NF="")' "$tmp_input1" > "$tmp_input2"
awk '{print $NF}' "$tmp_input2" > "$col5"
awk '!($NF="")' "$tmp_input2" > "$tmp_input1"
awk '{print $NF}' "$tmp_input1" > "$col4"
awk '!($NF="")' "$tmp_input1" > "$tmp_input2"
cat "$tmp_input2" > "$col3"
paste -d'\t' "$col1" "$col2" "$col3" "$col4" "$col5" "$col6" | column -s$'\t' -t > "$output"
rm -r "$tmp_dir"
이렇게 하면 여러 개의 tmp 파일(각 열에 하나씩, 원본 파일을 수정하기 위해 두 개)이 생성되고 원시 입력을 통해 처리되어 열 3만 남을 때까지 한 번에 한 열씩 제거됩니다. 그런 다음 모든 tmp 파일을 탭으로 구분된 형식으로 붙여넣고 column
필요에 따라 출력 형식을 지정합니다.
귀하가 입력한 내용을 바탕으로 다음을 수행합니다.
$ ./script.sh
$ cat output
AD AD100 Canillo 42.5833 1.6667 6
AD AD200 Encamp 42.5333 1.6333 6
AD AD300 Ordino 42.6 1.55 6
AD AD400 La Massana 42.5667 1.4833 6
AD AD500 Andorra la Vella 42.5 1.5 6
AD AD600 Sant Julià de Lòria 42.4667 1.5 6
AD AD700 Escaldes-Engordany 42.5 1.5667 6
AR 3636 POZO CERCADO (EL CHORRO (F), DPTO. RIVADAVIA (S)) Salta A -23.4933 -61.9267 3
AR 4123 LAS SALADAS Salta A -25.7833 -64.5 4
AR 4126 BARADERO Salta A -26.0833 -65.263 3
AR 4126 EL CUIBAL Salta A -26.0833 -65.263 3
AR 4126 LA ASUNCION Salta A -26.0833 -65.263 3
AR 4126 MIRAFLORES (TALA, DPTO. CANDELARIA) Salta A -26.0833 -65.263 3
AR 4141 TOLOMBON Salta A -26.2 -65.9167 4
AR 4141 QUISCA GRANDE Salta A -26.4367 -65.97 3
AR 4141 LA CIENEGUITA Salta A -26.4367 -65.97 3
AR 4141 MACHO RASTROJO Salta A -26.4367 -65.97 3
AR 4190 ROSARIO DE LA FRONTERA Salta A -25.8 -64.9667 4
AR 4190 OVANDO Salta A -25.8 -65.1 4
AR 4190 SAN ESTEBAN Salta A -25.8 -65.0333 3
AR 4190 LA BANDA (R. DE LA FRONTERA, DPTO. ROSARIO DE LA FRONTERA) Salta A -25.8 -65.0333 3
AR 4190 LA MATILDE Salta A -25.8 -65.0333 3
AR 4190 LAS PIEDRITAS Salta A -25.8 -65.0333 3
AR 4190 LOS POCITOS Salta A -25.8 -65.0333 3
AR 4190 OJO DE AGUA (ROSARIO DE LA FRONTERA, DPTO. R.DE LA FRONTERA) Salta A -25.8 -65.0333 3
AR 4190 POTRERILLO (R. DE LA FRONTERA, DPTO. ROSARIO DE LA FRONTERA) Salta A -25.8 -65.0333 3