다음과 같은 .csv 파일이 있습니다.
stack2@example.com,2009-11-27 01:05:47.893000000,example.net,127.0.0.1
overflow@example.com,2009-11-27 00:58:29.793000000,example.net,255.255.255.0
overflow@example.com,2009-11-27 00:58:29.646465785,example.net,256.255.255.0
...
파일에서 중복 전자 메일 (전체 행)을 제거해야합니다 (예 : overflow@example.com
위 예에 포함 된 행 중 하나 ). uniq
필드 1 (쉼표로 구분)에서만 사용하려면 어떻게합니까 ? 에 따르면 man
, uniq
열에 대한 옵션이 없습니다.
나는 무언가를 시도했지만 sort | uniq
작동하지 않습니다.
답변
sort -u -t, -k1,1 file
-u
독특한-t,
쉼표는 구분 기호입니다-k1,1
키 필드 1
검사 결과:
overflow@domain2.com,2009-11-27 00:58:29.793000000,xx3.net,255.255.255.0
stack2@domain.com,2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
답변
awk -F"," '!_[$1]++' file
-F
필드 구분 기호를 설정합니다.$1
첫 번째 필드입니다._[val]
val
해시_
(일반 변수)를 찾습니다 .++
증분하고 이전 값을 반환합니다.!
논리를 반환하지 않습니다.- 끝에 암시 적 인쇄가 있습니다.
답변
여러 열을 고려합니다.
열 1과 열 3을 기준으로 고유 한 목록을 정렬하고 제공하십시오.
sort -u -t : -k 1,1 -k 3,3 test.txt
-t :
콜론은 구분자입니다-k 1,1 -k 3,3
열 1과 열 3을 기준으로
답변
또는 uiq를 사용하려는 경우 :
<mycvs.cvs tr -s ',' ' ' | awk '{print $3" "$2" "$1}' | uniq -c -f2
제공합니다 :
1 01:05:47.893000000 2009-11-27 tack2@domain.com
2 00:58:29.793000000 2009-11-27 overflow@domain2.com
1
답변
복제본 중 마지막 사본을 유지하려면 사용할 수 있습니다.
tac a.csv | sort -u -t, -r -k1,1 |tac
내 요구 사항은 어느 것입니까
여기
tac
파일을 한 줄씩 뒤집습니다.
답변
여기 아주 좋은 방법이 있습니다.
먼저 고유성을 비교할 열이 고정 너비가되도록 내용의 형식을 지정하십시오. 이를 수행하는 한 가지 방법은 필드 / 열 너비 지정자 ( “% 15s”)와 함께 awk printf를 사용하는 것입니다.
이제 uniq의 -f 및 -w 옵션을 사용하여 선행 필드 / 열을 건너 뛰고 비교 너비 (열 너비)를 지정할 수 있습니다.
다음은 세 가지 예입니다.
첫 번째 예에서 …
1) 관심있는 열을 필드의 최대 너비보다 크거나 같은 고정 너비로 임시 설정하십시오.
2) -f uniq 옵션을 사용하여 이전 열을 건너 뛰고 -w uniq 옵션을 사용하여 너비를 tmp_fixed_width로 제한하십시오.
3) 열에서 후행 공백을 제거하여 너비를 “복원”합니다 (사전 후행 공백이 없다고 가정).
printf "%s" "$str" \
| awk '{ tmp_fixed_width=15; uniq_col=8; w=tmp_fixed_width-length($uniq_col); for (i=0;i<w;i++) { $uniq_col=$uniq_col" "}; printf "%s\n", $0 }' \
| uniq -f 7 -w 15 \
| awk '{ uniq_col=8; gsub(/ */, "", $uniq_col); printf "%s\n", $0 }'
두 번째 예에서 …
새 uniq 열 생성 1. uniq 필터가 적용된 후 제거하십시오.
printf "%s" "$str" \
| awk '{ uniq_col_1=4; printf "%15s %s\n", uniq_col_1, $0 }' \
| uniq -f 0 -w 15 \
| awk '{ $1=""; gsub(/^ */, "", $0); printf "%s\n", $0 }'
세 번째 예는 두 번째 예와 동일하지만 여러 열에 적용됩니다.
printf "%s" "$str" \
| awk '{ uniq_col_1=4; uniq_col_2=8; printf "%5s %15s %s\n", uniq_col_1, uniq_col_2, $0 }' \
| uniq -f 0 -w 5 \
| uniq -f 1 -w 15 \
| awk '{ $1=$2=""; gsub(/^ */, "", $0); printf "%s\n", $0 }'
답변
주어진 파일에 대해 특정 값을 가진 모든 것을 제거 해야하는 경우 grep -v를 수행하지 않는 이유는 무엇입니까?
예 : 두 번째 줄에서 “col2″값을 가진 모든 항목을 삭제하려면 : col1, col2, col3, col4
grep -v ',col2,' file > file_minus_offending_lines
이것으로 충분하지 않은 경우 일치하는 값이 다른 열에 표시되어 일부 선이 잘못 제거 될 수 있으므로 다음과 같이 할 수 있습니다.
문제의 열을 분리하기위한 awk : 예
awk -F, '{print $2 "|" $line}'
-F는 필드를 “,”로 구분하여 설정합니다. $ 2는 열 2를 의미하며 사용자 지정 구분 기호와 전체 행을 의미합니다. 그런 다음 위반 값으로 시작 하는 행을 제거하여 필터링 할 수 있습니다 .
awk -F, '{print $2 "|" $line}' | grep -v ^BAD_VALUE
그런 다음 구분 기호 앞에 물건을 제거하십시오.
awk -F, '{print $2 "|" $line}' | grep -v ^BAD_VALUE | sed 's/.*|//g'
(sed 명령에는 이스케이프 값이 포함되어 있지 않으므로 sed 명령이 느슨합니다. 또한 sed 패턴은 실제로 “[^ |] +”(예 : 구분 기호가 아닌 것)와 같아야합니다. 그러나 이것은 충분히 명확합니다.
