행의 열 수를 기준으로 CSV를 정렬하시겠습니까?

행의 열 수를 기준으로 CSV를 정렬하시겠습니까?

많은 레코드가 포함된 여러 개의 CSV 파일이 있습니다. 총 행 수는 134개여야 합니다. 많은 파일이 있고 각 행에는 고유한 열 수(15~200개)가 있습니다. 열 수에 따라 정렬해야 합니다.

다음을 사용하여 파일의 열 수를 계산할 수 있습니다.

$ awk -F"," '{print NF}' file # 1.csv

...다음과 같은 내용을 제공합니다.

134
134
134
5
25
133
...

이제 나중에 이를 기준으로 행을 정렬할 수 있도록 각 행에 이 숫자를 추가하고 싶습니다. 각 정보의 시작 부분에 이 정보를 추가하고 정렬하려면 어떻게 해야 합니까?

또한 값이 134인 파일을 각각의 개수에 따라 다른 파일 1개로 분할하고 싶습니다.

작은 입력 파일 예(총 3줄):

2,"A.B.C.D",50,"SDf3oa701-ab73-a0pcs90","7012218969217-1413752517-32448","SDf3oa701-ab73-a0pcs90","SIP",,"<[email protected]>;tag=70122","<[email protected]>",17,0,"00:01:57.827 GMT Oct 20 2014","00:00:00.000 UTC Jan 01 1970","00:01:57.870 GMT Oct 20 2014",3,"sp3",1904,"sp3",1904,"realm_IN","realmTERM_OUT",,,,"::",0,"::",0,,"::",0,"::",0,0,0,0,0,0,0,0,0,0,0,,,,"::",0,"::",0,,"::",0,"::",0,0,0,0,0,0,0,0,0,0,0,,,,"::",0,"::",0,,"::",0,"::",0,0,0,0,0,0,0,0,0,0,0,,,,"::",0,"::",0,,"::",0,"::",0,0,0,0,0,0,0,0,0,0,0,,,"Sw-buildabcd","GMT-03:00",0,"[email protected]",,,,,,"X.Y.Z.W:50","A.S.D.F:50","A.S.D.F:50","A.S.D.F:50",,1,2,1,404,"[email protected]",,,4493101
2,"A.B.C.D",50,,,,4493105
2,"A.B.C.D",50,,"[email protected]",,,4493106

답변1


이것을 추가 하려는 쉼표 구분으로 생각하십시오 -F,.
예를 들어awk -F, '$(NF+1)=NF' file

줄 끝에 숫자 추가

 awk '$(NF+1)=NF' file

입력하다

1
1 2 3
1 2
1 2 3 4 5 6
a b

산출

1 1
1 2 3 3
1 2 2
1 2 3 4 5 6 6
a b 2

행 정렬

 awk '{a[NF]=a[NF]?a[NF]"\n"$0:$0;x=x<NF?NF:x}END{for(i=1;i<=x;i++)if(i in a)print a[i]}'

입력하다

1
1 2 3
1 2
1 2 3 4 5 6
a b

산출

1
1 2
a b
1 2 3
1 2 3 4 5 6

다른 파일로 인쇄

예를 들어 필드 길이 4를 사용하고 134 또는 원하는 값으로 변경하세요.

 awk '{print > (NF>=4?"LargeFile.txt":"SmallFile.txt")}' file 

입력하다

1
1 2 3
1 2
1 2 3 4 5 6
a b

산출

LargeFile.txt

 1 2 3 4 5 6

SmallFile.txt

1
1 2 3
1 2
a b

답변2

@terdon의 답변과 유사하지만 다음을 포함합니다 sed.

{ seq -s, 10; seq -s, 5; seq -s, 15; } | 
tee - -

이것은 내 정보 파일입니다. 다음과 같습니다.

1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5
1,2,3,4,5
1,2,3,4,5
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15

그러면 다음과 같이 할 수 있습니다.

sed 'h;s/[^,]*//g;G;s/\n/ /' | sort -t\  -nk1,1

...이건...

,,,, 1,2,3,4,5
,,,, 1,2,3,4,5
,,,, 1,2,3,4,5
,,,,,,,,, 1,2,3,4,5,6,7,8,9,10
,,,,,,,,, 1,2,3,4,5,6,7,8,9,10
,,,,,,,,, 1,2,3,4,5,6,7,8,9,10
,,,,,,,,,,,,,, 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
,,,,,,,,,,,,,, 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
,,,,,,,,,,,,,, 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15

숫자는 거기에 없지만 숫자는 확실하다고 생각합니다. 선행 쉼표를 제거하려면 다음을 수행할 수 있습니다.

PIPELINE | sed 's/,* //'

...이건...

1,2,3,4,5
1,2,3,4,5
1,2,3,4,5
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15

지금까지 가장 상서로운 답변은 아닐 수도 있지만, 제가 이 게시물을 쓰기로 결정한 주된 이유는 쉼표로 구분된 134개의 항목이 포함된 줄을 다른 파일에 작성하고 싶다고 언급하셨기 때문입니다. 공교롭게도 이것은 간단한 일입니다 sed. 예를 들어, 위 시퀀스의 10개 필드가 포함된 행을 다음과 같이 작성한다고 가정해 보겠습니다 file2.

PIPELINE | sed '/^\([^,]*,[^,]*\)\{9\}$/w file2'
cat file2

산출

1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10

\{9\}위의 방법은 패턴의 9개 인스턴스를 지정하기 때문에 사용했습니다 . 즉, 9개의 구분 기호를 10개의 구분 필드로 만듭니다. 범위는 다음과 같이 간단하게 처리할 수도 있습니다.

PIPELINE | sed '/^\([^,]*,[^,]*\)\{4,9\}$/w file2'
cat file2

산출

1,2,3,4,5
1,2,3,4,5
1,2,3,4,5
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10

답변3

그러면 각 줄의 시작 부분에 (쉼표로 구분된) 필드 수를 추가하고 줄을 인쇄한 다음 모든 것을 정렬합니다.

awk -F"," '{print NF,$0}' *csv | sort -nk1,1

이는 -n숫자순으로 정렬하고 -k1,1첫 번째 필드에서만 정렬되도록 합니다. 정렬된 필드 수를 제거하려면 다음을 사용하십시오.

awk -F"," 'print NF,$0' *csv | sort -nk1,1 | cut -d ' ' -f 2- 

노트: 실제 데이터에 따라 쉽게 깨질 수 있습니다. 필드에 쉼표가 있을 수 있나요? 여러 줄에 걸쳐 있는 필드를 가질 수 있나요? 이것은 어떤 문제도 해결하지 못하는 매우 순진한 접근 방식입니다.

관련 정보