텍스트 처리-쉼표로 두 줄마다 조인


35

파일에 1000 줄 이상이 있습니다. 파일은 다음과 같이 시작됩니다 (행 번호 추가).

Station Name
Station Code
A N DEV NAGAR
ACND
ABHAIPUR
AHA
ABOHAR
ABS
ABU ROAD
ABR

두 줄을 모두 합쳐서 쉼표로 구분 된 항목으로 파일로 변환해야합니다. 최종 데이터는 다음과 같아야합니다

Station Name,Station Code
A N DEV NAGAR,ACND
ABHAIPUR,AHA
ABOHAR,ABS
ABU ROAD,ABR
...

내가 시도한 것은 셸 스크립트를 작성하고 그 echo사이에 쉼표로 작성하는 것입니다. 그러나 나는 여기서 일을 할 것이다 간단한 효과적인 한 라이너에있을 수 추측 sed/ awk.

어떤 아이디어?


@ l0b0 당신은 라인 번호가 "설명을 위해서만 있습니다"라는 OP의 의견을 편집했습니다 ...
jasonwryan

@jasonwryan 죄송합니다 . 설명을위한 이 있다고 생각했습니다 . 0 행의 구문 분석 오류
l0b0

답변:


39

단순히 cat(고양이를 좋아한다면 ;-) 사용하십시오 paste.

cat file.in | paste -d, - - > file.out

설명 : paste여러 파일에서 읽고 해당 행 (첫 번째 파일의 1 행과 두 번째 파일의 1 행)을 함께 붙여 넣습니다.

paste file1 file2 ...

파일 이름 대신 -(대시)를 사용할 수 있습니다 . pastefile1에서 첫 번째 줄을 가져옵니다 (stdin). 그런 다음 file2에서 첫 번째 행을 읽으려고합니다 (stdin이기도 함). 그러나 stdin의 첫 번째 줄은 이미 읽고 처리되었으므로 이제 입력 스트림에서 대기하는 것은 stdin 의 두 번째 줄이며, paste번째 줄에 행복하게 붙입니다. 이 -d옵션은 구분 기호를 탭이 아닌 쉼표로 설정합니다.

또는,

cat file.in | sed "N;s/\n/,/" > file.out

추신 : 예, 위의 내용을 단순화 할 수 있습니다

< file.in sed "N;s/\n/,/" > file.out

또는

< file.in paste -d, - - > file.out

사용하지 않는 장점이 cat있습니다.

그러나 나는 명확성을 이유로이 관용구 를 의도적으로 사용하지 않았다. 덜 장황하고 cat(CATS ARE NICE)를 좋아 한다. 편집하지 마십시오.

또는 고양이에 붙여 넣기를 선호하는 경우 (paste는 파일을 가로로 연결하는 명령이지만 cat은 세로로 연결하는 명령입니다) 다음을 사용할 수 있습니다.

paste file.in | paste -d, - -

다시 언급하면됩니다. 줄 번호는 파일의 일부가 아닙니다 :)
mtk

paste 명령은 완벽하게 당신이 그것에 대해 좀 더 설명을 적어주세요 수 있습니다 작동합니다. 하이픈 ??
mtk

2
하이픈은 "stdin에서 읽음"을 의미합니다. 동일한 입력 소스가 반복되면 paste는 출력 행당 여러 번 읽습니다.
dubiousjim

@sch : 멋진 편집, 나는 그것을 만지지 않을 것이다 :-)
1

1
당신의 cat주장 과 관련하여 . 않습니다 sed "N;s/\n/,/" file.in > file.out작동하지?
Bernhard

8

여기에 착륙하는 사람이 모든 선을 CSV 원 라이너로 결합하려는 경우

cat file | tr '\n' ','

3
sed 'N;s/\n/,/' file

sed를 사용하여 2 줄마다 join (N)을 연결하고 개행 (\ n)을 ","으로 바꿉니다.


3
paste -sd ',\n' file.in > file.out

또한 한 문자를 다른 문자로 바꾸는 것만으로 (다른 모든 줄 바꿈은 쉼표로) 입력 파일을 대신 사용할 수 있습니다.

paste -sd ',\n' file.in 1<> file.in

(하지만 에뮬레이트 된 POSIX paste가 비 유닉스 방식으로 취급 할 수 있는 CRLF 터미네이터 (예 : Microsoft)가있는 비 유닉스 시스템에서는 작동하지 않을 수 있습니다.


그게 1여기서 뭐하는거야 1<>? 오타입니까?
αғsнιη

@ αғsнιη, 이것을보십시오
iruvar

@iruvar 감사합니다
αғsнιη

2

순수한 Bash를 사용하는 하나의 라이너 (잠재적으로 수백만 개의 명령 실행자)가 있습니다.

(IFS=; while read -r name; do read -r code; printf '%s\n" "$name,$code"; done < file.in) > file.out

나는 저장하고 복원 할 필요가 없도록 서브 쉘 (포화)을 사용합니다 IFS. 소스가 소스 인 경우 사용자 환경을 망치지 않기 위해 수행해야 할 것 대안은 read에서 IFS= read -r name와 같이 새 IFS를 전달하는 것 IFS= read -r code입니다.

루프의 모든 명령이 셸에 내장되어 있기 때문에 성능이 좋으며 작은 파일에 대한 다른 솔루션보다 훨씬 빠릅니다. 그러나 많은 사람들은 그것을 나쁜 습관으로 생각하고 다른 것으로 일반화 할 때주의해야합니다.


일반적으로 환경 변화를 현지화하기 위해 서브 쉘을 사용하는 경우가 있습니다. 그러나이 경우에는 필요하지 않습니다. 대신 while IFS='\n' read -r name; do IFS='\n' read -r code ... done < file.in쉘 스크립트에서 종종 볼 수있는 관용어 인 대신 할 수 있습니다 . 의미 하는 -r플래그 read는 "stdin 스트림에서 문자 '\'다음에 문자 'n'을 개행 문자가 아닌 두 문자로 해석합니다." 아마도을 반복하는 것보다 서브 쉘을 만드는 것이 더 미학적 일 수 있습니다 IFS='\n'.
dubiousjim

@ dubiousjim : -r기술적으로 솔루션을 개선했습니다. 큰! 나는 변화를 IFS두 번 통과한다는 생각의 팬이 아닙니다 . 내가 하나의 독서를 사용했다면, 훌륭하지만 두 번은 아닙니다. 물론 그것은 의견 의 문제입니다 . 서브 쉘을 사용하는 것은 내가 말할 일반적인 Bash 지식보다 약간이므로 많은 사람들이 그 목적을 이해하는 데 어려움을 겪을 것입니다. 나쁜 일이야
삭제됨

2

완전한 답변을 얻으려면 가능한 awk해결책은 다음과 같습니다.

awk 'NR%2==1 {printf $0","} NR%2==0 { print $0}' *file*

@ downvoter : downvote를받을 자격이있는 내 대답에 어떤 문제가 있습니까? 어떻게 개선 할 수 있습니까?
Bernhard

아마도 게으른 때문에 printf? 스테이션 이름에 형식 지정자가 포함 된 경우 드물게 실패합니다. ( 예를 들어 pastebin.com/wgxFttrJ 를 참조하십시오 .) 그러나 이것은 추측 일뿐입니다.
manatwork

1

awk숙어 의 노인 오래된 밤

awk '{ORS=NR%2?",":"\n";print}' file
Station Name,Station Code
A N DEV NAGAR,ACND
ABHAIPUR,AHA
ABOHAR,ABS
ABU ROAD,ABR

awk '{ORS=NR%2?",":"\n"};1'짧고 관용구
cuonglm

@ cuonglm, 의심합니다. 이 경우에도 여전히 하나의 라이너 print이며 의도는 분명합니다. 나 같은 1노인에게도 분명 awk하지만 나는 선호한다print
iruvar

이것은 내가 찾은 첫 번째 간단한 솔루션으로 2 줄 이상으로 쉽게 구성 할 수 있습니다. sed검색하기 전에 한동안 싸웠지 만 awk4 줄마다 쉽게 결합했습니다. 나에게 여행을 저장했습니다 $EDITOR!
opello

0

펄도 가능합니다

perl -pe 's/^\d+\.\s+//;$.&1?chomp:print","' file


0

예를 들면 다음과 같습니다.

seq 0 70 | xargs -L 2 | sed 's/ /,/g'

출력 : (참고 : xargs -L number_of_columns두 줄뿐만 아니라 대부분의 열과 잘 작동합니다)

0,1
2,3
4,5
6,7
8,9
10,11
12,13
14,15
16,17
18,19
20,21
22,23
24,25
26,27
28,29
30,31
32,33
34,35
36,37
38,39
40,41
42,43
44,45
46,47
48,49
50,51
52,53
54,55
56,57
58,59
60,61
62,63
64,65
66,67
68,69
70

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.