Làm cách nào tôi có thể xóa từ thứ 5 của mỗi dòng trong một tệp?


13

Tôi muốn xóa từ thứ 5 của mỗi dòng trong một tệp.

Nội dung hiện tại của tệp:

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  

Sản lượng dự kiến:

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

Câu trả lời:


31

Thế còn 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' ' đặt dấu phân cách là không gian

  • -f1-4,6- chọn trường thứ nhất đến thứ 4 (từ), để lại trường thứ 5 và sau đó tiếp tục in từ thứ 6 sang phần còn lại.


11

Một giải pháp với cut:

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

Nhiều người -fkhông được hỗ trợ trong cut(GNU) của tôi ít nhất ..
heemayl 14/07/2015

Được hỗ trợ cắt BSD nhưng tôi thích phản hồi của bạn hơn của tôi.
fd0

1
Nếu GNU bị cắt, bạn sẽ lấy --complementcờ để đơn giản hóa mọi thứ : cut --complement -d ' ' -f5. Hãy nhớ chuyển hướng đầu ra sang một tệp mới, sau mvđó chuyển qua bản gốc.
Toby Speight

6

awk: xóa trường thứ 5

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

Nếu bạn muốn lưu tệp tại chỗ: /programming//q/16529716/7552

Bạn chỉ có thể xóa nội dung của trường thứ 5, nhưng để lại 2 dấu tách trường đầu ra liên tiếp:

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

lưu ý ở đây là việc thay đổi giá trị của bất kỳ trường nào trong awk có tác dụng phụ là viết lại toàn bộ "$ 0" chỉ với 1 dấu phân cách giữa mỗi trường. nên được tính đến nếu bạn muốn giữ bất kỳ sự liên kết nào (trừ khi gnu awk có tùy chọn tránh điều này? awk / nawk thông thường sẽ tính toán lại $ 0)
Olivier Dulac

Trong cả hai trường hợp, bạn định dạng lại dòng bằng một dấu phân cách duy nhất . Nếu có 2 dấu cách hoặc dấu cách + dấu cách trong dấu phân cách, kết quả là một khoảng trắng duy nhất được đặt đúng chỗ. Điều này hy vọng OK cho hầu hết các văn bản.
NeronLeVelu 16/07/2015

4

Với POSIX sed:

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

tại sao giới hạn lớp học là: alnum: _ và không phải bất cứ điều gì khác sau đó :blank:hay :space:?
NeronLeVelu 16/07/2015

@NeronLeVelu: Điều đó phụ thuộc vào cách bạn xác định những gì tạo ra một từ.
cuonglm 16/07/2015

@mikeerv; Bắt tốt đẹp! Tôi cập nhật câu trả lời của tôi.
cuonglm 16/07/2015

Là gì \(nhóm chụp \)cho?
mikeerv 16/07/2015

@mikeerv: tôi gõ sai, tôi vừa thử một số cách để giữ lại dấu phân cách.
cuonglm 16/07/2015

2

glenn đưa ra một giải pháp tương đương với

awk '{$ 5 = ""; in} ' tập tin

Như ông và những người khác đã chỉ ra, điều này

  1. dải khoảng trắng hàng đầu và dấu vết từ mỗi dòng,
  2. nén từng chuỗi khoảng trắng (khoảng trắng và / hoặc tab) vào một khoảng trắng và
  3. để lại hai khoảng trống giữa thứ tư và sáu từ.

Một hack để khắc phục vấn đề thứ ba là

awk '{$ 5 = ""; in} ' tập tin | sed / s / / '

Điều này sẽ vẫn để lại một hoặc nhiều (các) không gian được thêm vào cuối bất kỳ dòng nào có năm hoặc ít hơn các từ đi vào. Nếu bạn có thể xác định một từ sẽ không bao giờ xuất hiện trong đầu vào,

awk '{$ 5 = "kỳ lân"; in} ' tập tin | sed 's / * kỳ lân //'

sẽ xử lý ngay cả điều đó (nhưng nó vẫn để lại vấn đề 1 và 2).


2
 sed 's/^\(\([[:blank:]]*[^[:blank:]]\{1,\}\)\{4\}\)[[:blank:]]*[^[:blank:]]*/\1/' YourFile > Output.txt
  • posix sed dựa trên dấu tách không gian / tab (lớp meta [: blank:]])
  • giữ khoảng trắng sau từ thứ 5 nhưng xóa từ trước

Mạnh mẽ hơn (sed lấy mẫu dài nhất có thể và mẫu có *thể bỏ lỡ phân tách hoặc từ trong phiên bản đầu tiên) nhưng phiên bản dài hơn một chút

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

1
sed 's/[^[:blank:]]*//5'
mikeerv 16/07/2015

@mikeerv, cái này sẽ giữ cả dải phân cách xung quanh, sed 's/[[:blank:]*[^[:blank:]]*//5'tốt hơn. Điểm rất tốt. Tôi nghi ngờ rằng sed lấy mỗi char duy nhất làm thực thể nhưng nó lấy mô hình chưa bị phá vỡ lớn nhất làm thực thể
NeronLeVelu 16/07/2015

sed 's/[[:blank:]][^[:blank:]]*//4'sẽ loại bỏ hoàn toàn trường thứ 5.
mikeerv 16/07/2015

@mikeerv Giả sử không có không gian bắt đầu trên dòng (như trong mẫu)
NeronLeVelu

Trong trường hợp này, vâng, tôi nghĩ bạn đúng. Thông thường một điều như vậy sẽ là một trường null và hành vi sẽ đúng. Trong trường hợp này, bạn nên làm như @cuonglm đã làm và đảm bảo bạn tham chiếu một từ mỗi lần như sed 's/[[:blank:]][^[:blank:]][^[:blank:]]*//4', hoặc, w / GNU / BSD / toybox seds : sed -E 's/[[:blank:]][^[:blank:]]+//4'.
mikeerv

1

Perl.

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


-1

Sử dụng Perl> 5.10 (và xuất thành công tất cả các dòng: 0)): -

perl -nE '/^((\w+ +){4})\w+ *(.*)/; say $1.$3' file
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.