특정 줄에서 /를 제거하는 방법은 무엇입니까?

특정 줄에서 /를 제거하는 방법은 무엇입니까?

다음과 같은 파일이 있습니다

'ABC'|filler|'Y'|'john/1'|'text'
'ABC'|filler|'Y'|'john/1'|'te/xt'
'ABC'|filler|'N'|'mary/2'|'text'
'DEF'|filler|'N'|'jane/3'|'text'

초기 grep 이후,

$ wordY="'Y'|"
$ wordN="'N'|"
$ grep ABC test.txt | grep "$wordY\|$wordN'[[:alpha:]]+/"

돌아오는 중

'ABC'|filler|'Y'|'john/1'|'text'
'ABC'|filler|'Y'|'john/1'|'te/xt'    
'ABC'|filler|'N'|'mary/2'|'text'

/이제 이름만 제거하고 새 .txt 파일에 저장하고 싶습니다 .

그래서 내 이상적인 출력은

'ABC'|filler|'Y'|'john1'|'text'
'ABC'|filler|'Y'|'john1'|'te/xt'    -- / should not be removed for 'te/xt'
'ABC'|filler|'N'|'mary2'|'text'

출력을 얻으려면 명령에 어떻게 추가해야 합니까?

답변1

입력이 |필드 구분 기호로 사용되는 "간단한" CSV 파일이고 포함된 구분 기호나 줄 바꿈이 있는 필드가 없다고 가정하면 awk이를 사용하여 수정하려는 특정 필드를 처리할 수 있습니다.

$ awk -F '|' -v sq="'" 'BEGIN { OFS = FS } $1 == sq "ABC" sq { gsub("/","",$4); print } ' file
'ABC'|filler|'Y'|'john1'|'text'
'ABC'|filler|'Y'|'john1'|'te/xt'
'ABC'|filler|'N'|'mary2'|'text'

입력을 필드를 구분하는 줄바꿈으로 구분된 레코드 로 읽 -F '|'습니다 . 인라인 스크립트에서 작은따옴표를 처리하는 것은 까다로울 수 있고 코드를 읽을 수 없게 만들 수 있으므로 변수를 작은따옴표 문자로 설정하기도 합니다.awk|awkawksq

코드는 첫 번째 필드의 값이 인 레코드를 감지하고 'ABC'해당 레코드의 경우 (잠재적으로) 수정된 레코드를 출력하기 전에 네 번째 필드에서 슬래시를 제거합니다.

또한 첫 번째 필드 데이터를 하드코딩하지 않고 감지하려는 전체 문자열을 변수(여기 query)에 전달할 수도 있습니다.

$ awk -F '|' -v query="'ABC'" 'BEGIN { OFS = FS } $1 == query { gsub("/","",$4); print } ' file
'ABC'|filler|'Y'|'john1'|'text'
'ABC'|filler|'Y'|'john1'|'te/xt'
'ABC'|filler|'N'|'mary2'|'text'

아래 설명(현재 삭제됨)에 언급된 대로 다음을 수행할 수 있습니다.가능한수정된 레코드의 네 번째 열에 실제로 슬래시가 포함된 경우에만 출력됩니다. 이건 아마단순화하다우리의 명령은 다음과 같습니다:

awk -F '|' -v query="'ABC'" 'BEGIN { OFS = FS } $1 == query && gsub("/","",$4)' file

gsub()명령은 대체된 수를 반환합니다. 즉, 원래 네 번째 필드에 있는 슬래시 수를 반환합니다. 그렇지 않은 경우 함수는 0을 반환하고 그 결과 로깅이 발생합니다.아니요인쇄됩니다.

세 번째 필드가 다음과 같은지 확인하시겠습니까? 'Y'아니면 다음을 'N'사용할 수 있습니까?

awk -F '|' -v query="'ABC'" -v yn="^'[YN]'$" '
    BEGIN { OFS = FS }
    $1 == query && $3 ~ yn && gsub("/","",$4)' file

여기서는 세 번째 필드가 변수와 일치해야 하는 정규식을 전달한 awk다음 yn이를 사용하여 $3 ~ yn테스트를 수행합니다. 표현식은 또는 와 ^'[YN]'$일치합니다 .'Y''N'

답변2

사용sed

$ sed -En "\~^('ABC[^YN]*(Y|N)'\|'[[:alpha:]]+)/~s//\1/p" input_file
'ABC'|filler|'Y'|'john1'|'text'
'ABC'|filler|'Y'|'john1'|'te/xt'
'ABC'|filler|'N'|'mary2'|'text'

답변3

다음을 수행할 수 있습니다.

$ awk 'BEGIN{FS=OFS="|"; q="\047"} 
       ($1==q"ABC"q)&&($3~q"Y|N"q)&&($4~"/") { sub("/","",$4);print }
      ' test.txt

'ABC'|filler|'Y'|'john1'|'text'
'ABC'|filler|'Y'|'john1'|'te/xt'
'ABC'|filler|'N'|'mary2'|'text'

필드 구분 기호와 출력 필드 구분 기호를 동일한 값( )으로 설정합니다 |. 그런 다음 따옴표 문자를 사용하여 변수를 생성하고 q="047"(이렇게 하면 스크립트의 나머지 부분이 단순화됨) 다음 3가지를 테스트합니다.

  • 첫 번째 필드는 와 정확히 같습니다 'ABC'.
  • 세 번째 필드는 'Y'또는 입니다 'N'.
  • 네 번째 필드에는 실제로 /.

그런 다음 다음을 수행하십시오.

  • /네 번째 필드의 첫 번째 필드를 삭제합니다.
  • 전체 줄을 인쇄합니다.

이는 정규식을 사용하여 grep Test ABC에 게시한 grep 명령과 다릅니다. 그것이 당신이 원하는 것이라면, 또는 그냥으로 $1 == q"ABC"q바꾸 십시오 (이렇게 하면 입력 라인 전체에서 ABC를 찾을 수 있습니다).$1 ~ "ABC"~"ABC"

이러한 값 중 하나에 대한 모든 입력 라인을 테스트하는 것도 Y중복되는 것 같습니다. N그렇다면 두 번째 테스트를 삭제할 수 있습니다.

이는 awk 명령을 다음과 같이 단순화합니다.

awk '($1~/ABC/)&&sub("/","",$4)' FS="|" OFS="|" test.txt

네 번째 필드의 모든 항목을 교체해야 하는 경우 /변경 기능을 사용할 수 있습니다. 일부 운영 체제(현재 운영 체제 포함)에서는subgsub이전 awk구현gsub를 지원하지 않을 수 있습니다.

답변4

tr다음과 같은 콘텐츠의 경우:

grep ABC test.txt | grep "$wordY|$wordN'[[:alpha:]]+/" | tr -d '/'

tr는 "번역"의 약어이며 특정 세트에 나타나는 문자를 제거하거나 다른 세트의 동일한 위치에 있는 문자로 대체하여 변경할 수 있습니다.

-d매개변수는 "문자 제거" 모드를 선택합니다. 여기서는 지정된 세트(여기서 세트는 하나의 문자 "/"임)의 문자가 출력에 다시 쓰여지기 전에 입력에서 제거됩니다.

자세한 내용은 을 참조하십시오 man tr.

관련 정보