그래서 나는 각각 8개의 열과 많은 행을 가진 많은 수의 파일을 가지고 있습니다. 다음은 그중 하나의 머리의 예입니다.
ID Ct 1 2 3 4 5 6
1 0 consensus - - - - -
2 0 consensus - - - - -
3 0 consensus consensus consensus consensus consensus consensus
4 0 consensus - consensus - - -
5 0 - AT AT GC GC AT
6 0 consensus - - - consensus -
7 0 consensus - - - - -
8 0 consensus consensus consensus - consensus consensus
9 0 consensus - - - - -
마지막 6개 열이 적어도 5/6 이상 차지하는 모든 행을 분리하고 싶습니다. 따라서 ID 3, 5, 8(4, 6, 9행)은 내 머리에서 나온 것입니다. 따라서 2개 미만의 열이 있는 모든 행에 "-"가 유효하도록 하고 싶습니다.
나는 프로그램이 두 번째 열에서 얼마나 많은 열을 차지했는지 계산했기 때문에 간단한 awk 스크립트를 사용하여 이 작업을 수행할 수 있었습니다. 더 이상 이 작업을 수행할 수 없는 것 같습니다. 가장 좋은 접근 방식은 무엇입니까?
답변1
얼마나 멀리 갈 것인가?
awk 'gsub(/-/, "&") < 2' file
ID Ct 1 2 3 4 5 6
3 0 consensus consensus consensus consensus consensus consensus
5 0 - AT AT GC GC AT
8 0 consensus consensus consensus - consensus consensus
이해합니다? rg는 아무 말도 하지 않습니다. 원하는 출력 - 단일 출력 파일, 출력 줄 앞에 파일 이름이 붙는 것, 원본 파일과 비슷한 이름을 가진 새 파일, 또는 무엇을 원하십니까?
편집하다(새 파일 이름에 주석을 단 후):
awk 'gsub(/-/, "&") < 2 {print > (FILENAME ".new")}' /path/to/file/*
답변2
모든 파일이 동일한 디렉터리에 있으면 for 루프/glob을 사용하여 각 파일을 반복하고 해당 파일에 대해 awk 명령을 실행할 수 있습니다.
for file in /path/to/files/*; do
awk '{
count=0
for (i=3;i<=8;i++) {
if ($i == "-") {
count++
}
}
if ((count <= 1)) {
print
}
}' "$file"
done
각 행에 대해 3-8열을 반복하며 해당 열의 값이 -
추가된 값 과 같으면 행의 값이 1보다 count
크면 count
인쇄되지 않습니다.
답변3
Perl은 이런 종류의 작업에 편리합니다. 특히 grep
명시적인 루프 없이 필드별로 작업을 수행할 수 있으며 그 결과(스칼라 컨텍스트에서 평가할 때) 일치 횟수가 제공됩니다. 예를 들어
$ perl -lane 'print if 3 > grep { $_ eq "-" } splice @F, 2' file
ID Ct 1 2 3 4 5 6
3 0 consensus consensus consensus consensus consensus consensus
5 0 - AT AT GC GC AT
8 0 consensus consensus consensus - consensus consensus