여러 개의 파일(행 30000개와 열 32개로 구성된 약 20개 파일)이 있는데 동일한 문자열로 시작하는 행만 유지해야 합니다. 나는 이러한 사례가 내가 필요로 하는 것과 매우 유사하다는 것을 알았지만 어떻게 적용해야 할지 모르겠습니다.
두 개의 서로 다른 열을 사용하여 여러 파일(2개 이상)을 비교합니다.
두 개의 서로 다른 파일에 있는 두 열의 값을 비교하고 차이의 절대값이 작은 최대값보다 작은 전체 행을 에코하는 방법은 무엇입니까?
내 경우에는 각 파일의 첫 번째 열이 12자의 문자열로 구성되어 있는데, 모든 파일에 존재하는 문자열로 시작하는 줄만 유지하면 된다. (입력 파일당 하나의 파일 또는 위의 경우와 같이 하나의 출력 파일도 작동합니다). 내 파일은 다음과 같습니다.
파일 1:
-13 -5 0 19.3769 46.9197 1
-13 -4 -2 347.911 57.7232 1
-13 -4 -1 38.5696 39.0027 1
-13 -4 0 2227.39 124.894 1
-13 -3 -3 113.001 40.2117 1
-13 -3 -2 850.847 78.2881 1
파일 2:
-13 -5 0 2.19085 50.4632 1
-13 -4 -2 283.628 56.7731 1
-13 -4 -1 41.179 48.6423 1
-13 -4 0 1753.54 125.88 1
-13 -3 -3 28.2363 40.6518 1
-13 -3 -2 562.736 66.0301 1
-13 -3 -1 750.747 77.2795 1
산출파일 1:
-13 -5 0 19.3769 46.9197 1
-13 -4 -2 347.911 57.7232 1
-13 -4 -1 38.5696 39.0027 1
-13 -3 -3 113.001 40.2117 1
-13 -3 -2 850.847 78.2881 1
산출파일 2
-13 -5 0 2.19085 50.4632 1
-13 -4 -2 283.628 56.7731 1
-13 -4 -1 41.179 48.6423 1
-13 -3 -3 28.2363 40.6518 1
-13 -3 -2 562.736 66.0301 1
답변1
한 가지 접근 방식은 먼저 여러 파일에 있는 12개의 초기 문자 집합을 모두 찾는 것입니다.
cut -c-12 file* | sort | uniq -c
위의 명령은 cut
이름이 로 시작하는 각 파일의 처음 12자를 인쇄한 다음 file
문자를 정렬하고 각 줄에서 찾은 횟수를 추가합니다 uniq -c
. 샘플 파일에서 이 명령을 실행하면 다음이 반환됩니다.
$ cut -c-12 file* | sort | uniq -c
1 -13 -3 -1
2 -13 -3 -2
2 -13 -3 -3
2 -13 -4 0
2 -13 -4 -1
2 -13 -4 -2
2 -13 -5 0
따라서 첫 번째 줄을 제외한 모든 줄이 두 파일에 모두 나타납니다. 이제 필요한 횟수(귀하의 경우 20회)만큼 발생하는 행만 유지하세요.
cut -c-12 file* | sort | uniq -c | rev | sed -n 's/ 20 *$//p' | rev
rev
거꾸로 인쇄하면 됩니다. 여기서는 각 행의 마지막 필드가 표시된 횟수를 계산하는 데 사용하고 있습니다. 그런 다음 이를 전달 sed
하고 공백, 20 및 0 이상의 공백으로 끝나는 줄만 인쇄하도록 지시합니다. 이렇게 하면 20번 나타나는 줄만 유지되고 마침내 rev
원래 형식으로 돌아갑니다.
이제 grep
검색할 문자열 목록으로 전체 콘텐츠를 전달할 수 있습니다.
$ grep -f <(cut -c-12 file* | sort | uniq -c |
rev | sed -n 's/ 20 *$//p' | rev) file*
-13 -5 0 19.3769 46.9197 1
-13 -4 -2 347.911 57.7232 1
-13 -4 -1 38.5696 39.0027 1
-13 -4 0 2227.39 124.894 1
-13 -3 -3 113.001 40.2117 1
-13 -3 -2 850.847 78.2881 1
쉘이 해당 <()
형식을 지원하지 않는 경우 결과를 cut
별도의 파일에 저장하여 사용하거나 루프에서 실행할 수 있습니다.
cut -c-12 file* | sort | uniq -d |
while IFS= read -r l; do grep -- "^$l" file1; done
각 파일의 출력을 별도의 파일에 넣으려면 다음을 사용하십시오.
cut -c-12 file* | sort | uniq -c | rev | sed -n 's/ 20 *$//p' | rev > list
for f in file*; do grep -f list "$f" > "$f.new"; done