특정 문자열이 포함된 필드 제거

특정 문자열이 포함된 필드 제거

file1특정 문자열(제 경우에는 밑줄 문자)이 포함된 필드만 삭제하려는 탭으로 구분된 필드가 여러 개 있습니다 ( _모든 줄을 삭제하지 않음).

cat file1
357M        2054_
357_        154=        1900_
511_        419X        1481_        34=

다음 정보를 얻고 싶습니다.

cat file2
357M
154=
419X        34=

다음과 같이 이러한 필드를 제거했습니다.

cat file1 | perl -pe 's/\w+_\s*//g'
357M    154=        419X        34=

하지만 열 수를 변경하고 싶지 않기 때문에 형식이 좋지 않습니다.

나는 또한 다음을 시도했습니다.

cat file1 | sed 's/[0-9]*_//g'
357M
          154=
          419X         34=

하지만 그 빈 열을 제거하고 싶습니다.

실제로 작동하는 무차별 접근 방식은 다음과 같습니다.

cat file1 | sed 's/[0-9]*_//g' | tr -s '\t' '\t' | sed 's/^[ \t]*//g'
357M
154=
419X         34=

마지막 명령은 (1) 밑줄이 포함된 모든 필드를 제거합니다. (2) 연속된 여러 탭을 하나의 탭으로 바꿉니다. (3) 선행 탭을 제거합니다. 그래도 그렇게 우아하지는 않습니다.

어떤 제안이 있으십니까?

답변1

고려하다:

sed 's/[^\t]*_//; s/\t[^\t]*_/\t/g' < input

이는 두 가지(조건부) 대체를 수행합니다.

  • 첫 번째는 "탭이 아닌 문자 뒤에 밑줄이 오는 모든 (0개 이상의) 문자"를 의미하며 "(없음)"으로 대체됩니다.
  • 두 번째는 "탭 다음에 탭이 아닌 문자(0개 이상) 다음에 밑줄이 오는 것"을 "탭"으로 바꾸는 것을 의미하며 해당 검색 패턴을 찾은 횟수만큼 이 작업을 수행합니다.

제거해야 할 선행 필드를 찾으려면 첫 번째 검색이 필요합니다. 두 번째 검색에서는 나머지를 제거합니다.

이렇게 하면 해당 열의 원래 필드가 유지됩니다.

357M
        154=
        419X            34=

필드를 완전히 제거하려면 검색에 탭을 포함하고 텍스트를 바꾸십시오.

sed 's/[^\t]*_\t//; s/\t[^\t]*_//g' < input

결과 :

357M
154=
419X    34=

답변2

이것을 간단하게 사용할 수 있습니다 sed.

sed 's/\w*_\s*//;/^$/d' infile.txt 

/^$/dfoo_밑줄 이나 그 자체로 _끝나는 필드가 하나만 포함된 줄은 빈 줄이 제거됩니다 .

결과는 다음과 같습니다.

357M
154=
419X    34=

답변3

항상 "무차별 대입과 무지" 접근 방식이 있습니다.

  • 잘못된 필드 제거
  • 여러 탭을 단일 탭으로 변환
  • 줄의 시작 부분에서 단일 태그를 제거합니다.
  • 줄 끝에서 개별 탭 제거

똑똑하지도 영리하지도 않지만 작동합니다.

다음에서 TAB은 리터럴 TAB 문자를 의미합니다.

sed -e 's/[0-9]*_//g' -e 's/TABTAB/TAB/g' -e 's/^TAB//' -e 's/TAB$//'

예를 들어

$ cat x
357M    2054_
357_    154=    1900_
511_    419X    1481_   34=
$ sed -e 's/[0-9]*_//g' -e 's/            /       /g' -e 's/^     //' -e 's/     $//' < x
357M
154=
419X    34=

답변4

내부 필드에만 관심이 있는 경우(예:아니요행의 첫 번째 또는 마지막 필드). 하지만 모든 영역을 살펴보고 싶습니다. 그래서 각 행의 마지막 필드를 처리하지 않는 것처럼 보이게 하는 솔루션이 있습니다.

sed -e 's/$/\t/' -e 's/[^\t]*_[^\t]*\t//g' -e 's/\t$//'

이것

  1. 각 줄의 끝에 탭 문자를 추가합니다(따라서 효과적으로n+1 비어 있는 번째 필드).
  2. (탭이 아닌 문자열)을 포함하는 모든 필드를 찾아 _ 해당 필드와 다음 탭 문자를 제거합니다(비어 있는 문자열로 대체). 이는 다음에 적용됩니다.N 번째 필드(즉, 원래 줄의 마지막 필드)는 1단계에서 끝에 탭 문자를 추가했기 때문입니다.
  3. 줄 끝에서 추가 탭 문자를 제거합니다.

빈 필드를 유지하는 기능이 있습니다(귀하가 요청하지 않았다는 것을 알고 있지만 사용 가능한 것을 확인하면 감사할 것입니다).

$ 고양이 파일 3
갈색 개가 뛰어올랐다.
        민첩한 여우가 게으른 여우보다 낫다
4년 _년
        7년전 성적..

$(위 명령)파일 3
갈색 개가 뛰어올랐다.
        민첩한 여우가 게으른 여우보다 낫다
사 년
        7년전 성적..

sedPS 사용 중인 버전 에 따라 대신 명령에 실제 탭을 입력해야 할 수도 있습니다 \t. 또는 bash를 사용하는 경우 include 를 $'…'사용할 수 있습니다 .sed\t

관련 정보