Câu trả lời:
head
hoạt động quá:
head -c 100 file # returns the first 100 bytes in the file
..sẽ trích xuất 100 byte đầu tiên và trả lại chúng.
Điều thú vị khi sử dụng head
cho điều này là cú pháp cho các tail
kết quả khớp:
tail -c 100 file # returns the last 100 bytes in the file
Bạn có thể kết hợp những thứ này để có được phạm vi byte. Ví dụ: để lấy 100 byte thứ hai từ một tệp, hãy đọc 200 byte đầu tiên head
và sử dụng đuôi để lấy 100 byte cuối cùng:
head -c 200 file | tail -c 100
head
, sau đó sử dụng tail
để lấy 10 byte cuối cùng, ví dụ:head -c 20 file | tail -c 10
Bạn có thể sử dụng dd để trích xuất các phần byte tùy ý.
Ví dụ,
dd skip=1234 count=5 bs=1
sẽ sao chép các byte 1235 đến 1239 từ đầu vào đến đầu ra của nó và loại bỏ phần còn lại.
Để chỉ lấy năm byte đầu tiên từ đầu vào chuẩn, hãy làm:
dd count=5 bs=1
Lưu ý rằng, nếu bạn muốn chỉ định tên tệp đầu vào, dd có phân tích cú pháp đối số kiểu cũ, vì vậy bạn sẽ thực hiện:
dd count=5 bs=1 if=filename
Cũng lưu ý rằng dd thông báo rõ ràng những gì nó đã làm, vì vậy để loại bỏ điều đó, hãy làm:
dd count=5 bs=1 2>&-
hoặc là
dd count=5 bs=1 2>/dev/null
dd bs=1
buộc dd phải đọc và viết một ký tự tại một thời điểm, điều này sẽ chậm hơn nhiều so với head
khi số lượng lớn. Tuy nhiên, nó không đáng chú ý đối với count = 5.
dd
có vẻ như sẽ làm được điều này .. Chúc mừng!
head -c
thực hiện các dd bs=5 count=1
phương pháp làm việc
đầu :
head - xuất phần đầu tiên của tệp
đầu [ OPTION ] ... [ FILE ] ...
In 10 dòng đầu tiên của mỗi FILE ra đầu ra tiêu chuẩn. Với nhiều FILE, hãy đặt trước mỗi tệp một tiêu đề cho tên tệp. Khi không có FILE hoặc khi FILE là -, hãy đọc đầu vào chuẩn.
Đối số bắt buộc đối với tùy chọn dài cũng là bắt buộc đối với tùy chọn ngắn.
-c , --bytes = [-] N
in N byte đầu tiên của mỗi tệp; với '-' đứng đầu, in tất cả trừ N byte cuối cùng của mỗi tệp
head -Line_number file_name | tail -1 |cut -c Num_of_chars
tập lệnh này cung cấp số ký tự chính xác từ dòng và vị trí cụ thể, ví dụ:
head -5 tst.txt | tail -1 |cut -c 5-8
cung cấp các ký tự ở dòng 5 và các ký tự từ 5 đến 8 của dòng 5,
Ghi chú : tail -1
dùng để chọn dòng cuối cùng được hiển thị bởi đầu.
bạn cũng có thể cắt dòng ra và sau đó cắt nó như sau:
tên tệp grep 'text' | cắt -c 1-5
Tôi biết câu trả lời là trả lời cho một câu hỏi được hỏi cách đây 6 năm ...
Nhưng tôi đã tìm kiếm thứ gì đó tương tự trong vài giờ và sau đó phát hiện ra rằng: cut -c thực hiện chính xác điều đó, với một phần thưởng bổ sung mà bạn cũng có thể chỉ định bù đắp.
cut -c 1-5 sẽ trở lại Xin chào và cut -c 7-11 sẽ trở lại thế giới . Không cần bất kỳ lệnh nào khác
Mặc dù điều này đã được trả lời / chấp nhận từ nhiều năm trước, nhưng câu trả lời được chấp nhận hiện tại chỉ đúng cho các mã hóa một byte cho mỗi ký tự như iso-8859-1 hoặc cho các tập hợp con byte đơn của các bộ ký tự byte biến (như ký tự Latinh trong UTF-8). Ngay cả khi sử dụng các mối ghép nhiều byte thay vào đó vẫn chỉ hoạt động đối với các mã hóa đa byte cố định như UTF-16. Do hiện nay UTF-8 đang trên đường trở thành một tiêu chuẩn chung và khi xem danh sách các ngôn ngữ này theo số lượng người bản ngữ và danh sách 30 ngôn ngữ hàng đầu theo cách sử dụng bản ngữ / thứ cấp này , điều quan trọng là phải chỉ ra kỹ thuật đơn giản thân thiện với ký tự byte biến đổi (không dựa trên byte), sử dụng cut -c
và tr
/sed
với các lớp ký tự.
So sánh những điều sau đây không thành công gấp đôi do hai sai lầm / giả định trọng tâm tiếng Latinh phổ biến liên quan đến vấn đề byte so với ký tự (một là head
so với cut
, còn lại là [a-z][A-Z]
so với [:upper:][:lower:]
):
$ printf 'Πού μπορώ να μάθω σανσκριτικά;\n' | \
$ head -c 1 | \
$ sed -e 's/[A-Z]/[a-z]/g'
[[unreadable binary mess, or nothing if the terminal filtered it]]
đối với điều này (lưu ý: điều này hoạt động tốt trên FreeBSD, nhưng cả cut
và tr
trên GNU / Linux vẫn mang tiếng Hy Lạp trong UTF-8 đối với tôi mặc dù):
$ printf 'Πού μπορώ να μάθω σανσκριτικά;\n' | \
$ cut -c 1 | \
$ tr '[:upper:]' '[:lower:]'
π
Một câu trả lời khác gần đây hơn đã đề xuất "cắt", nhưng chỉ vì vấn đề phụ mà nó có thể được sử dụng để chỉ định hiệu số tùy ý, không phải vì vấn đề ký tự liên quan trực tiếp so với byte.
Nếu bạn cut
không xử lý -c
chính xác các mã hóa byte biến, đối với "các X
ký tự đầu tiên " (thay thế X
bằng số của bạn), bạn có thể thử:
sed -E -e '1 s/^(.{X}).*$/\1/' -e q
- được giới hạn ở dòng đầu tiênhead -n 1 | grep -E -o '^.{X}'
- được giới hạn ở dòng đầu tiên và chuỗi hai lệnh mặc dùdd
- đã được gợi ý trong các câu trả lời khác, nhưng thực sự rất rườm ràsed
tập lệnh phức tạp với bộ đệm cửa sổ trượt để xử lý các ký tự trải dài trên nhiều dòng, nhưng điều đó có lẽ cồng kềnh / dễ hỏng hơn là chỉ sử dụng một cái gì đó nhưdd
Nếu bạn tr
không xử lý các lớp ký tự với mã hóa byte biến một cách chính xác, bạn có thể thử:
sed -E -e 's/[[:upper:]]/\L&/g
(Dành riêng cho GNU)printf 'Πού ' | cut -c 1
chỉ trả về vô nghĩa ... nó hoạt động giống như 'đầu'
Đây là một tập lệnh đơn giản kết thúc bằng cách sử dụng dd
phương pháp được đề cập ở đây:
#!/usr/bin/env bash
function show_help()
{
IT="
extracts characters X to Y from stdin or FILE
usage: X Y {FILE}
e.g.
2 10 /tmp/it => extract chars 2-10 from /tmp/it
EOF
"
echo "$IT"
exit
}
if [ "$1" == "help" ]
then
show_help
fi
if [ -z "$1" ]
then
show_help
fi
FROM=$1
TO=$2
COUNT=`expr $TO - $FROM + 1`
if [ -z "$3" ]
then
dd skip=$FROM count=$COUNT bs=1 2>/dev/null
else
dd skip=$FROM count=$COUNT bs=1 if=$3 2>/dev/null
fi
mkfifo /tmp/test.fifo; echo "hello world">/tmp/test.fifo & head -c 5 /tmp/test.fifo
cũng tiêu thụ" world\n"
mà bị mất vĩnh viễn.