Khi tôi thực thi các lệnh trong Bash (hoặc cụ thể, wc -l < log.txt
), đầu ra chứa một ngắt dòng sau nó. Làm sao để tôi bỏ nó đi?
Khi tôi thực thi các lệnh trong Bash (hoặc cụ thể, wc -l < log.txt
), đầu ra chứa một ngắt dòng sau nó. Làm sao để tôi bỏ nó đi?
Câu trả lời:
Nếu đầu ra dự kiến của bạn là một dòng đơn , bạn chỉ cần xóa tất cả các ký tự dòng mới khỏi đầu ra. Sẽ không có gì lạ khi chuyển sang tiện ích 'tr' hoặc Perl nếu được ưu tiên:
wc -l < log.txt | tr -d '\n'
wc -l < log.txt | perl -pe 'chomp'
Bạn cũng có thể sử dụng thay thế lệnh để xóa dòng mới:
echo -n "$(wc -l < log.txt)"
printf "%s" "$(wc -l < log.txt)"
Xin lưu ý rằng tôi không đồng ý với quyết định của OP về việc chọn câu trả lời được chấp nhận. Tôi tin rằng người ta nên tránh sử dụng 'xargs' nếu có thể. Vâng, nó là một món đồ chơi thú vị. Không, bạn không cần nó ở đây.
Nếu đầu ra dự kiến của bạn có thể chứa nhiều dòng , bạn có một quyết định khác:
Nếu bạn muốn xóa NHIỀU ký tự dòng mới khỏi cuối tệp, một lần nữa sử dụng thay thế cmd:
printf "%s" "$(< log.txt)"
Nếu bạn muốn xóa hoàn toàn ký tự dòng mới LAST khỏi tệp, hãy sử dụng Perl:
perl -pe 'chomp if eof' log.txt
Lưu ý rằng nếu bạn chắc chắn rằng bạn có một ký tự dòng mới mà bạn muốn xóa, bạn có thể sử dụng 'head' từ GNU coreutils để chọn mọi thứ trừ byte cuối cùng. Điều này sẽ khá nhanh chóng:
head -c -1 log.txt
Ngoài ra, để hoàn thiện, bạn có thể nhanh chóng kiểm tra vị trí các ký tự dòng mới (hoặc đặc biệt khác) trong tệp của mình bằng cách sử dụng cờ 'cat' và cờ 'show-all'. Ký tự ký hiệu đô la sẽ chỉ ra phần cuối của mỗi dòng:
cat -A log.txt
tr --delete '\n'
.
| tr -d '\r'
Một chiều:
wc -l < log.txt | xargs echo -n
echo -n `wc -l log.txt`
IFS
) vào một khoảng trắng . Ví dụ : echo "a b" | xargs echo -n
; echo -n $(echo "a b")
. Điều này có thể hoặc không thể là một vấn đề cho trường hợp sử dụng.
-e
, nó sẽ được hiểu là tùy chọn echo
. Nó luôn an toàn hơn để sử dụng printf '%s'
.
xargs
là rất chậm trên hệ thống của tôi (và tôi nghi ngờ nó cũng ở trên các hệ thống khác), vì vậy printf '%s' $(wc -l log.txt)
có thể nhanh hơn, vì printf
thường là một nội dung (Cũng bởi vì không có chuyển hướng thông tin). Không bao giờ sử dụng backticks, chúng đã bị phản đối trong các phiên bản POSIX mới hơn và có nhiều nhược điểm.
Ngoài ra còn có hỗ trợ trực tiếp để loại bỏ khoảng trắng trong thay thế biến Bash :
testvar=$(wc -l < log.txt)
trailing_space_removed=${testvar%%[[:space:]]}
leading_space_removed=${testvar##[[:space:]]}
trailing_linebreak_removed=${testvar%?}
Nếu bạn chỉ định đầu ra của nó cho một biến, bash
sẽ tự động loại bỏ khoảng trắng:
linecount=`wc -l < log.txt`
printf đã cắt dòng mới cho bạn:
$ printf '%s' $(wc -l < log.txt)
Chi tiết:
%s
người giữ vị trí chuỗi. %s\n
), nó sẽ không."$(command)"
, các dòng mới bên trong sẽ được giữ nguyên - và chỉ dòng mới theo sau sẽ bị xóa. Shell đang thực hiện tất cả các công việc ở đây - printf
chỉ là một cách để hướng kết quả thay thế lệnh trở lại stdout
.
$( )
cấu trúc. Đây là bằng chứng:printf "%s" "$(perl -e 'print "\n"')"
$ printf '%s' "$(wc -l < log.txt)"
Nếu bạn muốn xóa chỉ dòng mới nhất , hãy chuyển qua:
sed -z '$ s/\n$//'
sed
sẽ không thêm \0
vào cuối luồng nếu bộ phân cách được đặt thành NUL
thông qua -z
, trong khi đó để tạo tệp văn bản POSIX (được xác định là kết thúc bằng a \n
), nó sẽ luôn xuất ra một bản cuối cùng \n
mà không có -z
.
Ví dụ:
$ { echo foo; echo bar; } | sed -z '$ s/\n$//'; echo tender
foo
bartender
Và để chứng minh không NUL
thêm:
$ { echo foo; echo bar; } | sed -z '$ s/\n$//' | xxd
00000000: 666f 6f0a 6261 72 foo.bar
Để xóa nhiều dòng mới , hãy bỏ qua:
sed -Ez '$ s/\n+$//'
sed
không cung cấp -z
.
Nếu bạn muốn in đầu ra của bất cứ thứ gì trong Bash mà không có dòng cuối, bạn lặp lại nó bằng công -n
tắc.
Nếu bạn đã có nó trong một biến rồi, hãy lặp lại nó với dòng mới được cắt xén:
$ testvar=$(wc -l < log.txt)
$ echo -n $testvar
Hoặc bạn có thể làm điều đó trong một dòng, thay vào đó:
$ echo -n $(wc -l < log.txt)
echo -n $(wc -l < log.txt)
có tác dụng tương tự.