Linux에서 파일의 마지막 열을 삭제하는 방법


25

열 번호가 무엇인지 모르는 동안 txt 파일의 마지막 열을 삭제하고 싶습니다. 어떻게해야합니까?

예:

입력:

1223 1234 1323 ... 2222 123
1233 1234 1233 ... 3444 125
0000 5553 3455 ... 2334 222

그리고 내 출력을 원합니다.

1223 1234 1323 ... 2222
1233 1234 1233 ... 3444
0000 5553 3455 ... 2334

이를 수행하는 방법에는 여러 가지가 있습니다. 예와 예상 결과를 추가하십시오.
heemayl

확인 @heemayl 내가 그랬어
ZARA

감사합니다 .. 열 탭이 분리되어 있거나 공백으로 구분되어 있습니까?
heemayl

@heemayl 공간 deliminator입니다
ZARA

답변:


43

awk:

awk 'NF{NF-=1};1' <in >out

또는:

awk 'NF{NF--};1' <in >out

또는:

awk 'NF{--NF};1' <in >out

이것은 부두처럼 보이지만 작동합니다. 이 awk 명령 각각에는 세 부분이 있습니다.

첫 번째는입니다 NF. 이는 두 번째 부분의 전제 조건입니다. NF행의 필드 수를 포함하는 변수입니다. AWK에서는 0이 아니거나 빈 문자열 인 경우 상황이 true ""입니다. 따라서 두 번째 부분 ( NF감소 되는 위치) 은 NF0이 아닌 경우에만 발생합니다 .

두 번째 부분 ( NF-=1 NF--또는 --NF)은 NF변수 에서 하나를 빼는 것입니다 . 필드를 변경할 때 (이 경우 마지막 필드 제거) 기본적으로 공백으로 구분 된 모든 필드를 awk재구성 $0하고 연결 하기 때문에 마지막 필드가 인쇄되지 않습니다 . $0더 이상 마지막 필드를 포함하지 않았습니다.

마지막 부분은 1입니다. 그것은 마법이 아니며 단지 의미하는 표현으로 사용됩니다 true. 경우 awk모든 관련 조치없이 true로 표현 평가하여, awk기본 동작입니다 print $0.


@JJoao : 아, 고마워 --. 현재 ;1POSIX 호환 이 필요 합니다.
cuonglm

내 본능은 for 루프를 사용하는 것이지만 훨씬 간결하고 영리합니다.
Sergiy Kolodyazhnyy

5
기본이 아닌 구분자를 사용하는 경우 몇 가지 사항을 변경해야합니다. ,당신의 구분자가 있다고 가정 :awk -F',' 'BEGIN { OFS = FS }; NF { NF -= 1 }; 1' < in > out
Mr. Llama

1
NF를 줄이면 POSIX에 의해 정의되지 않은 동작이 발생합니다. 실행중인 awk에 따라 다른 출력을 얻을 수 있습니다. 일부 awk는 원하는대로 마지막 필드를 제거하고 일부는 전혀 아무것도하지 않으며 다른 일부는 구문 오류 또는 기타 다른 것을보고 할 수 있습니다.
Ed Morton

16

grepPCRE와 함께 사용 :

$ grep -Po '.*(?=\s+[^\s]+$)' file.txt 
1223 1234 1323 ... 2222
1233 1234 1233 ... 3444
0000 5553 3455 ... 2334

GNU 사용 sed:

$ sed -r 's/(.*)\s+[^\s]+$/\1/' file.txt 
1223 1234 1323 ... 2222
1233 1234 1233 ... 3444
0000 5553 3455 ... 2334

1
@ramin Sure .. 당신 은 새로운 질문 으로 물어 주시기 바랍니다 (이 사이트가 작동하는 방식입니다) :)
heemayl

@ramin 시간 제한이나 경고가 있습니까?
heemayl

그것은 이것이 표준 질문이 아니라고 말합니다!
zara

@ramin Ok .. 관리자에게 연락하면 도움이 될 수 있습니다 ..btw 질문과 관련하여 이전 품질 보증을 확인 했습니까? 질문이 이미 요청되고 답변
되었을

3
" Linux에서 파일 이름을 바꾸려면 어떻게해야합니까? "와 같은 기본적인 질문은하지 마십시오 . Google을 사용하십시오.
Christoffer Hammarström

11

펄 사용하기 :

perl -lane '$,=" ";pop(@F);print(@F)' in

rev+ 사용 cut:

rev in | cut -d ' ' -f 2- | rev

5

GNU sed 사용하기 :

sed -r 's/\s+\S+$//' input.txt

보다 일반적으로 이것은 OSX의 BSD sed와 GNU sed에서 작동합니다.

sed 's/[[:space:]]\{1,\}[^[:space:]]\{1,\}$//' input.txt

1

분리 문자가 항상 단일 문자 인 경우 (두 개 이상의 연속 분리 문자가 빈 필드를 지정 함) head입력 파일의 첫 번째 행만 분리 문자를 계산하고 ( n구분 기호는 필드 수를 의미 함 n+1) st 필드 cut에서 인쇄 하는 데 사용 1합니다. n탭으로 구분 된 입력 을 사용하여 최대 th 필드까지 (두 번째에서 마지막 필드 까지 ) :

n=$(head -n 1 infile | tr -dc \\t | tr \\t \\n | wc -l)
cut -f1-$n infile > outfile

또는 예를 들어 csv 파일을 사용하는 경우 :

n=$(head -n 1 infile | tr -dc , | tr , \\n | wc -l)
cut -d, -f1-$n infile > outfile

시간이 있으면 나중에 몇 가지 벤치 마크를 실행하지만 큰 입력 으로이 솔루션은 첫 번째 줄에서 최소한의 처리를 수행하므로 정규식을 사용하는 다른 솔루션보다 빠릅니다. cut이 작업에 최적화 된 필드를 사용합니다 .


1

다음 중 하나를 사용할 수 있습니다.

sed 's/[[:space:]]*[^[:space:]]*$//' file

awk '{sub(/[[:space:]]*[^[:space:]]*$/,"")}1' file

0

vim 사용하기 :

vim에서 파일 열기

vim <filename> 

커서가 다른 곳에있을 경우를 대비하여 첫 번째 행으로 이동하십시오.

gg

"Q"라는 매크로 만들기 qq현재 라인의 뒤쪽으로 이동, $다음 마지막 공간으로 돌아갑니다, F(문자 공백 자본 F) 다음 라인의 끝을 통해 현재 위치에서 삭제 D다음 라인에 가서 j하고 로 매크로 기록을 중지하십시오 q.

qq$F Djq

이제 @q각 줄마다 매크로를 반복 할 수 있습니다 .
를 눌러 @@마지막 매크로를 반복하거나 더 쉽게 할 수도 있습니다 .

99@q

매크로를 99 번 반복합니다.
참고 : 숫자가 줄과 정확히 일치하지 않아야합니다.


0

비슷한 문제가 있지만 필드 구분 기호가 다른 사람들의 경우이 awk방법은 필드 구분 기호를 올바르게 유지합니다.

$ cat file 
foo.bar.baz
baz.bar.foo
$ awk -F'.' 'sub(FS $NF,x)' file
foo.bar
baz.bar
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.