파일에서 모든 줄의 5 번째 단어를 어떻게 삭제합니까?


13

파일에서 각 줄의 5 번째 단어를 삭제하고 싶습니다.

파일의 현재 내용 :

File is not updated or and will be removed  
System will shut down f within 10 seconds  
Please save your work 55 or copy to other location  
Kindly cooperate with us D  

예상 출력 :

File is not updated and will be removed  
System will shut down within 10 seconds  
Please save your work or copy to other location  
Kindly cooperate with us

답변:


31

방법에 대해 cut:

$ cut -d' ' -f1-4,6- file.txt 
File is not updated and will be removed  
System will shut down within 10 seconds  
Please save your work or copy to other location  
Kindly cooperate with us
  • -d' ' 구분자를 공백으로 설정

  • -f1-4,6- 첫 번째에서 네 번째 필드 (워드)를 선택하고 다섯 번째 필드를 그대로 둔 다음 6에서 나머지까지 인쇄를 계속합니다.


11

솔루션 cut:

cut -d ' ' -f1-4 -f6- FILE

적어도 -fcut(GNU)에서 다중 지원되지 않습니다 ..
heemayl

BSD 컷에서 지원되지만 내 응답보다 낫습니다.
fd0

1
GNU 컷이라면 다음 --complement과 같이 단순화 하는 플래그를 얻습니다 cut --complement -d ' ' -f5. 출력을 새 파일로 경로 재 지정한 다음 mv원래 파일로 재 지정하십시오 .
Toby Speight

6

awk : 5 번째 필드 제거

awk '{for (i=5; i<NF; i++) $i = $(i+1); NF--};1' file

파일을 제자리에 저장하려면 /programming//q/16529716/7552

5 번째 필드의 내용을 지울 수는 있지만 두 개의 연속 출력 필드 구분 기호가 남습니다.

awk '{$5 = ""};1' file

여기서주의해야 할 점은 awk에서 필드 값을 변경하면 각 필드 사이에 하나의 구분 기호 만 사용하여 전체 "$ 0"을 다시 쓰는 부작용이 있다는 것입니다. 정렬을 유지하려면 gnu awk가 이것을 피하는 옵션이 없다면? awk / nawk가 $ 0를 재 계산합니다)
Olivier Dulac

두 경우 모두 단일 구분 기호로 줄을 다시 포맷하십시오 . 구분 기호에 2 개의 공백 또는 공백 + 탭이 있으면 결과는 단일 공백입니다. 이것은 대부분의 텍스트에 대해 다행입니다.
NeronLeVelu

4

POSIX sed로 :

sed -e 's/[^[:alnum:]_][[:alnum:]_][[:alnum:]_]*//4' <file

왜 클래스를 : alnum :으로 제한하고 _ 그다음 :blank:또는 :space:?
NeronLeVelu

@NeronLeVelu : 단어를 정의하는 방법에 따라 다릅니다.
cuonglm

@mikeserv; 좋은 캐치! 내 답변을 업데이트했습니다.
cuonglm

무엇 \(캡처 그룹 \)에 대해?
mikeserv

@ mikeserv : 내 잘못 입력하면 구분 기호를 유지하는 몇 가지 방법을 시도했습니다.
cuonglm

2

glenn 은 다음과 같은 솔루션을 제공했습니다.

awk '{$ 5 = ""; print} ' 파일

그와 다른 사람들이 지적했듯이, 이것은

  1. 모든 줄에서 앞뒤 공백을 제거합니다.
  2. 공백 (각 공백 및 / 또는 탭)의 각 문자열을 단일 공백으로 압축합니다.
  3. 네 번째 단어와 여섯 단어 사이에 두 개의 공백이 남습니다.

세 번째 문제를 해결하기위한 해킹은

awk '{$ 5 = ""; print} ' 파일 | sed 's ///'

이렇게해도 5 개 이하의 단어가 들어가는 줄 끝에 하나 이상의 공백이 남게됩니다. 입력에 절대 나타나지 않는 단어를 식별 할 수 있으면,

awk '{$ 5 = "unicorn"; print} ' 파일 | sed 's / * unicorn //'

그것조차도 처리 할 것입니다 (그러나 여전히 문제 1과 2를 남깁니다).


2
 sed 's/^\(\([[:blank:]]*[^[:blank:]]\{1,\}\)\{4\}\)[[:blank:]]*[^[:blank:]]*/\1/' YourFile > Output.txt
  • 공백 / 탭 구분자 (메타 클래스 [: blank :]])를 기반으로하는 POSIX sed
  • 다섯 번째 단어 뒤에 다음 공간을 유지하지만 이전 단어는 제거하십시오.

더 강력 함 (sed는 가능한 한 가장 긴 패턴을 취하고 패턴 *은 첫 번째 버전에서 분리 또는 단어를 놓칠 수 있음)

sed 's/^\([[:blank:]]*\([^[:blank:]]\{1,\}[[:blank:]]\{1,\}\)\{4\}\[^[:blank:]]\{1,\}/\1/' YourFile > Output.txt

1
sed 's/[^[:blank:]]*//5'
mikeserv

@ mikeserv, 이것은 주변 구분 기호를 모두 유지하는 sed 's/[[:blank:]*[^[:blank:]]*//5'것이 좋습니다. 아주 좋은 지적입니다. 나는 sed가 각각의 단일 문자를 하나의 엔티티로 취하는 것을 의심했지만 엔티티로서 가장 큰 훼손되지 않은 패턴을 취합니다
NeronLeVelu

sed 's/[[:blank:]][^[:blank:]]*//4'5 번째 필드를 완전히 제거합니다.
mikeserv

@mikeserv 라인에 시작 공간이 없다고 가정 (샘플에서와 같이)
NeronLeVelu

이 경우에는 그렇습니다. 일반적으로 이러한 것은 null 필드이며 동작은 정확합니다. 이 경우 @cuonglm 그랬던 것처럼 할 당신이 때마다 같은 단어를 참조 할 수 있도록해야한다 sed 's/[[:blank:]][^[:blank:]][^[:blank:]]*//4'w / GNU / BSD / toybox, 또는 sedS : sed -E 's/[[:blank:]][^[:blank:]]+//4'.
mikeserv

1

펄.

perl -ne 'print $_ =~ /^(\w+ +\w+ +\w+ +\w+ +)\w+ (.*)/,"\n"' file


-1

Perl> 5.10 사용 (그리고 모든 줄을 성공적으로 출력 : 0)) :-

perl -nE '/^((\w+ +){4})\w+ *(.*)/; say $1.$3' file
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.