Cần di chuyển dòng cuối cùng của tệp sang dòng thứ hai của cùng một tệp


8

Tôi có một tệp 'thử nghiệm' trong linux với dữ liệu bên dưới.

aaaaaa
bbbbbb
cccccc
dddddd
eeeeee

Tôi cần phải cắt dòng cuối cùng của tập tin này và đặt nó ở vị trí thứ hai. Nó phải trông như dưới đây.

aaaaaa
eeeeee
bbbbbb
cccccc
dddddd

Câu trả lời:


9

Vấn đề này thực sự có thể dễ thực hiện nhất ed, vì về cơ bản nó là trình soạn thảo văn bản có thể viết được, thay vì bộ xử lý luồng. edVí dụ, bằng cách sử dụng , bạn không phải lưu tất cả các dòng của tệp vào một mảng, vì nó đã làm điều đó cho bạn.

# Create test file
~> printf "%s\n" aaaaaa bbbbbb cccccc dddddd eeeeee >test.txt
~> cat test.txt
aaaaaa
bbbbbb
cccccc
dddddd
eeeeee

# Use ed to open the file, move the last line after the first, save, and quit
~> printf "%s\n" '$m1' wq | ed test.txt
35
35
~> cat test.txt
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd

5

Giữ phương thức đệm:

sed '$x;1!H;1p;$!d;x;s/\n//
' <<\IN
aaaaaa
bbbbbb
cccccc
dddddd
eeeeee
IN

... nó sẽ Hcũ mọi dòng !không phải là đầu tiên, và đầu tiên nó pgợi ý. Trên $dòng cuối cùng, nó xthay đổi khoảng giữ và mẫu trước khi thực hiện Hcũ - lấy các dòng đã lưu được nối vào dòng cuối cùng - sau đó dxóa khỏi đầu ra tất cả các dòng !không phải là dòng $cuối cùng.

Trên $dòng cuối cùng, nó xthay đổi không gian một lần nữa, s///loại bỏ \nký tự ewline đầu tiên - chăm sóc phần bổ sung thêm trên dòng 2 - sau đó tự động in lại rất nhiều.

ĐẦU RA:

aaaaaa
eeeeee
bbbbbb
cccccc
dddddd

không sử dụng bộ đệm Giữ:

cat <<\IN >infile
aaaaaa
bbbbbb
cccccc
dddddd
eeeeee
IN

... Chỉ để lưu ví dụ của bạn vào một tệp thực tế ...

sed '1p;$!d;r infile' <infile | sed '3d;$d'

Rằng chuyển hướng có <infileđể là người đầu tiên seds' stdin, mà chỉ prints dòng đầu tiên trước khi deleting từ đầu ra tất cả các dòng mà !không phải là $cuối cùng. Dòng cuối cùng là autoprinted, nhưng nó cũng là dòng duy nhất mà trên đó các lệnh cuối cùng được thực hiện - đó là rEAD ra toàn bộ infile một lần nữa để stdout. Tất cả điều đó được chuyển qua |đường ống đến ống thứ hai sedmà sau đó chỉ phải dtách khỏi đầu ra thứ ba và dòng đầu vào cuối cùng để hoàn thành việc sắp xếp lại.

ĐẦU RA:

aaaaaa
eeeeee
bbbbbb
cccccc
dddddd

mát mẻ, +1. Tôi không nhớ bạn đã từng đăng awkgiải pháp, bạn có phải là một sedfan hâm mộ lớn hoặc có lẽ bạn đã viết sed? ;-)
iruvar

@ 1_CR - tôi không biết cách sử dụng awk- tôi chưa bao giờ thử. có thể một ngày nào đó ...
mikeerv

2

Một sự chấp nhận ngây thơ bằng cách sử dụng awk:

~$ awk '{a[NR]=$0}END{print a[1];print a[NR];for(i=2;i<NR;i++){print a[i]}}' f
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd

Bạn lưu trữ mọi dòng trong amảng, sau đó in mảng theo thứ tự bạn muốn (dòng thứ nhất, dòng cuối cùng ( NR) và từ 2 đến áp chót.

Sử dụng kết hợp đầu / đuôi và sed:

~$ head -1 f;tail -1 f;sed '1d;$d' f
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd

In dòng đầu tiên, dòng cuối cùng và với sed xóa dòng đầu tiên và cuối cùng.


Chỉ với sed, tôi chỉ có thể tìm thấy lệnh này. Tôi chắc chắn có những cách tốt hơn:

~$ sed '${p;x;s/^\n//;p};2,${H;d}' f
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd

Nếu đó là dòng đầu tiên, hãy in nó (mặc định).
Từ dòng thứ hai, đặt nó vào bộ đệm giữ ( H) và xóa trong không gian mẫu ( d). Và nếu đó là dòng cuối cùng, hãy in nó ( p), sau đó lấy bộ đệm giữ ( x), xóa dòng trống ( s/^\n//) và in nó ( p).


Bản năng đầu tiên của tôi sẽ là sử dụng phương pháp đầu / đuôi. Một thay thế cho sedmột phần sẽ là một cái gì đó như head -n -1 f | tail -n +2.
Sparhawk

@Sparhawk -1cú pháp cho headkhông có di động.
mikeerv

1

Với perl:

perl -e 'my @lines = <>; print for @lines[0, $#lines, 1..$#lines-1]' file

Với awk:

$ awk '
    {lines[NR]=$0}
    END{
        print lines[1], lines[NR];
        for (i=2; i<NR; i++) {print lines[i]}
    }
' OFS=$'\n' file

ĐẦU RA

aaaaaa
eeeeee
bbbbbb
cccccc
dddddd
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.