Một phương pháp khá hiệu quả nếu bạn tệp không quá lớn là đọc tất cả trong bộ nhớ, trong một mảng, một dòng trên mỗi trường sử dụng mapfile
(đây là nội dung Bash ≥4):
mapfile -t array < file.txt
Sau đó, bạn có thể echo tất cả các dòng bạn muốn trong bất kỳ thứ tự, ví dụ:
printf '%s\n' "${array[4]}" "${array[2]}" "${array[9]}" "${array[5]}"
để in các dòng 5, 3, 10, 6. Bây giờ bạn sẽ cảm thấy đó là một chút vụng về rằng các trường mảng bắt đầu bằng một số 0
để bạn phải bù đắp số của mình. Điều này có thể dễ dàng chữa khỏi với -O
tùy chọn mapfile
:
mapfile -t -O 1 array < file.txt
này sẽ bắt đầu gán để array
tại chỉ số 1, do đó bạn có thể in dòng của bạn 5, 3, 10 và 6 như:
printf '%s\n' "${array[5]}" "${array[3]}" "${array[10]}" "${array[6]}"
Cuối cùng, bạn muốn thực hiện một chức năng bao bọc cho việc này:
printlines() {
local i
for i; do printf '%s\n' "${array[i]}"; done
}
để bạn c một trạng thái chỉ:
printlines 5 3 10 6
Và tất cả đều là Bash thuần túy, không có công cụ bên ngoài!
Như @glennjackmann gợi ý trong các ý kiến bạn có thể tận dụng chức năng helper cũng chăm sóc của việc đọc các tập tin (thông qua như là đối số):
printlinesof() {
# $1 is filename
# $2,... are the lines to print
local i array
mapfile -t -O 1 array < "$1" || return 1
shift
for i; do printf '%s\n' "${array[i]}"; done
}
Sau đó, bạn có thể sử dụng nó như:
printlinesof file.txt 5 3 10 6
Và nếu bạn cũng muốn xử lý stdin:
printlinesof() {
# $1 is filename or - for stdin
# $2,... are the lines to print
local i array file=$1
[[ $file = - ]] && file=/dev/stdin
mapfile -t -O 1 array < "$file" || return 1
shift
for i; do printf '%s\n' "${array[i]}"; done
}
sao cho
printf '%s\n' {a..z} | printlinesof - 5 3 10 6
cũng sẽ hoạt động.
+1 rất đẹp. Yêu cầu bash v4 cho 'mapfile'. Tôi muốn tăng cường điều đó bằng cách truyền tên tệp và thực hiện mapfile trong hàm: 'printlines() {local i array; mapfile -t -O 1 mảng <"$ 1"; thay đổi; cho tôi; làm printf '% s \ n' "$ {mảng [i]}"; làm xong; }; printlines file.txt 5 3 10 6' –
Tôi thích câu trả lời này nhất, ngay cả khi nó không "mở rộng" nếu tệp quá lớn. –