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
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:
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. ed
Ví 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
sed '$x;1!H;1p;$!d;x;s/\n//
' <<\IN
aaaaaa
bbbbbb
cccccc
dddddd
eeeeee
IN
... nó sẽ H
cũ mọi dòng !
không phải là đầu tiên, và đầu tiên nó p
gợi ý. Trên $
dòng cuối cùng, nó x
thay đổi khoảng giữ và mẫu trước khi thực hiện H
cũ - lấy các dòng đã lưu được nối vào dòng cuối cùng - sau đó d
xó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ó x
thay đổi không gian một lần nữa, s///
loại bỏ \n
ký 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.
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd
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 sed
s' stdin
, mà chỉ p
rints dòng đầu tiên trước khi d
eleting 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à r
EAD 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 sed
mà sau đó chỉ phải d
tá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.
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd
awk
- tôi chưa bao giờ thử. có thể một ngày nào đó ...
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 a
mả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
).
sed
một phần sẽ là một cái gì đó như head -n -1 f | tail -n +2
.
-1
cú pháp cho head
không có di động.
awk
giải pháp, bạn có phải là mộtsed
fan hâm mộ lớn hoặc có lẽ bạn đã viếtsed
? ;-)