Nếu tôi có đầu ra thực sự dài từ một lệnh (một dòng) nhưng tôi biết tôi chỉ muốn các ký tự [x] (giả sử 8) đầu tiên của đầu ra, cách dễ nhất để có được điều đó là gì? Không có bất kỳ dấu phân cách nào.
Nếu tôi có đầu ra thực sự dài từ một lệnh (một dòng) nhưng tôi biết tôi chỉ muốn các ký tự [x] (giả sử 8) đầu tiên của đầu ra, cách dễ nhất để có được điều đó là gì? Không có bất kỳ dấu phân cách nào.
Câu trả lời:
Một cách là sử dụng cut
:
command | cut -c1-8
Điều này sẽ cung cấp cho bạn 8 ký tự đầu tiên của mỗi dòng đầu ra. Vì cut
là một phần của POSIX, nên có khả năng nó sẽ có mặt trên hầu hết các Thông báo.
cut -c
chọn ký tự; cut -b
hoặc head -c
chọn byte. Điều này tạo ra sự khác biệt ở một số địa phương (trong thực tế, khi sử dụng UTF-8).
cut -c-8
sẽ chọn từ ký tự 1 đến 8.
cut
tương đương trên Windows là?
command | dd bs=8 count=1 2>/dev/null
. Không nói nó ngắn hơn hay vượt trội. Chỉ là một sự thay thế khác.
cut
, cut -c
hoạt động như thế cut -b
(nghĩa là, nó không hoạt động chính xác cho các ký tự nhiều byte).
Đây là một số cách khác để chỉ có 8 ký tự đầu tiên.
command | head -c8
command | awk '{print substr($0,1,8);exit}'
command | sed 's/^\(........\).*/\1/;q'
Và nếu bạn có bash
var=$(command)
echo ${var:0:8}
command | sed 's/\(.\{8\}\).*/\1/'
hoặc nếu sed của bạn hỗ trợ nó : command | sed -r 's/(.{8}).*/\1/'
; Mặt khác, +1
head -c
đếm byte , không phải ký tự. Tương tự, trong số các triển khai Awk chính, chỉ GNU awk xử lý chính xác các ký tự nhiều byte - FreeBSD Awk và Mawk thì không.
Nếu bạn có trình bao đủ nâng cao (ví dụ: phần sau sẽ hoạt động trong Bash, không chắc chắn về dấu gạch ngang), bạn có thể làm:
read -n8 -d$'\0' -r <(command)
Sau khi thực hiện read ... <(command)
, các ký tự của bạn sẽ ở trong biến shell REPLY
. Nhập help read
để tìm hiểu về các tùy chọn khác.
Giải thích: -n8
đối số để read
nói rằng chúng tôi muốn tối đa 8 ký tự. Các -d$'\0'
nói đọc cho đến khi một null, chứ không phải là một dòng mới. Bằng cách này, việc đọc sẽ tiếp tục cho 8 ký tự ngay cả khi một trong các ký tự trước đó là một dòng mới (nhưng không phải là một ký tự không). Một cách khác -n8 -d$'\0'
là sử dụng -N8
, đọc chính xác 8 ký tự hoặc cho đến khi stdin đạt EOF. Không có dấu phân cách được vinh danh. Điều đó có thể phù hợp với nhu cầu của bạn hơn, nhưng tôi không biết có bao nhiêu vỏ sò có một lần đọc tôn vinh -N
trái ngược với tôn vinh -n
và -d
. Tiếp tục với lời giải thích: -r
nói bỏ qua \
-escapes, do đó, ví dụ, chúng tôi coi \\
là hai ký tự, thay vì là một ký tự \
.
Cuối cùng, chúng tôi làm read ... <(command)
chứ không phải command | read ...
vì ở dạng thứ hai, việc đọc được thực thi trong một lớp con sau đó được thoát ngay lập tức, làm mất thông tin bạn vừa đọc.
Một tùy chọn khác là thực hiện tất cả quá trình xử lý của bạn bên trong lớp con. Ví dụ:
$ echo abcdefghijklm | { read -n8 -d$'\0' -r; printf "REPLY=<%s>\n" "$REPLY"; }
REPLY=<abcdefgh>
cut
.
read -n <num>
; cảnh báo nhỏ: Bash 3.x (vẫn còn trên hệ điều hành) hiểu nhầm <num>
là số byte và do đó không thành công với các ký tự nhiều byte; điều này đã được sửa trong Bash 4.x.
Một giải pháp lót khác bằng cách sử dụng mở rộng tham số
echo ${word:0:x}
EG: word="Hello world"
echo ${word:0:3} or echo ${word::3}
o/p: Hel
EG.2: word="Hello world"
echo ${word:1:3}
o/p: ell
x=8; echo ${word:0:$x}
thay vì mã hóa số nguyên.
Đây là di động:
a="$(command)" # Get the output of the command.
b="????" # as many ? as characters are needed.
echo ${a%"${a#${b}}"} # select that many chars from $a
Để xây dựng một chuỗi các ký tự có độ dài thay đổi có câu hỏi riêng của nó ở đây .
Tôi gặp vấn đề này khi tự tạo các tệp tổng kiểm tra trong kho lưu trữ maven. Thật không may, cut -c
luôn luôn in ra một dòng mới ở cuối đầu ra. Để ngăn chặn mà tôi sử dụng xxd
:
command | xxd -l$BYTES | xxd -r
Nó xuất ra chính xác $BYTES
byte, trừ khi command
đầu ra của nó ngắn hơn, thì chính xác là đầu ra đó.
cut
dòng mới của trailing là đưa nó vào:| tr -d '\n'