Shell = Kiểm tra nếu biến bắt đầu bằng #


16

Tôi sẽ rất cảm ơn nếu bạn có thể giúp tôi tìm hiểu, làm thế nào để xác định xem nội dung của một biến có bắt đầu bằng dấu băm không:

#!bin/sh    

myvar="#comment asfasfasdf"

if [ myvar = #* ] 

cái này không hoạt động

Cảm ơn!

Jans


1
Tôi sẽ xem xét khả năng có thể có khoảng trắng trước thẻ băm khi kiểm tra "nhận xét", nếu đó thực sự là những gì bạn đang làm.
rthomson

Khi bạn chấp nhận một câu trả lời liên quan đến một bashgiải pháp, có lẽ bạn có thể chỉnh sửa câu hỏi của mình, vì nó ngụ ý rằng bạn muốn có một sh/ dashgiải pháp.
Charles Roberto Canato

Tôi khuyên bạn nên sử dụng một đường dẫn tuyệt đối trong #!dòng làm đường dẫn tương đối trong dòng đó rõ ràng được lấy tương đối với thư mục hiện tại của quá trình thực thi tập lệnh chứ không liên quan đến vị trí của tập lệnh.
kasperd

Câu trả lời:


20

Cách tiếp cận ban đầu của bạn sẽ hoạt động tốt nếu bạn thoát khỏi hàm băm :

$ [[ '#snort' == \#* ]]; echo $?
0

Một cách tiếp cận khác sẽ cắt bỏ ký tự đầu tiên của nội dung của biến, sử dụng "Mở rộng chuỗi con":

if [[ ${x:0:1} == '#' ]]
then
    echo 'yep'
else
    echo 'nope'
fi

yep

Từ trang Bash man:

   ${parameter:offset}
   ${parameter:offset:length}
          Substring  Expansion.   Expands  to  up  to length characters of
          parameter starting at the character  specified  by  offset.   If
          length  is omitted, expands to the substring of parameter start-
          ing at the character specified by offset.  length and offset are
          arithmetic   expressions   (see  ARITHMETIC  EVALUATION  below).
          length must evaluate to a number greater than or equal to  zero.
          If  offset  evaluates  to  a number less than zero, the value is
          used as an offset from the end of the value  of  parameter.   If
          parameter  is  @,  the  result  is  length positional parameters
          beginning at offset.  If parameter is an array name indexed by @
          or  *,  the  result is the length members of the array beginning
          with ${parameter[offset]}.  A negative offset is taken  relative
          to  one  greater  than the maximum index of the specified array.
          Note that a negative offset must be separated from the colon  by
          at  least  one  space to avoid being confused with the :- expan-
          sion.  Substring indexing is zero-based  unless  the  positional
          parameters are used, in which case the indexing starts at 1.

Để xem trang người đàn ông này, tôi nên gõ người đàn ông gì?
duleshi

Đó là trang người Bash, vì vậy " man bash" nên làm điều đó.
Insyte

2
Đó là bashism, nhưng thẻ là về "shell" chứ không phải "bash" :(.
pevik

11

Phiên bản tương thích POSIX:

[ "${var%${var#?}}"x = '#x' ] && echo yes

hoặc là:

[ "${var#\#}"x != "${var}x" ] && echo yes

hoặc là:

case "$var" in
    \#*) echo yes ;;
    *) echo no ;;
esac

1
+1 cho câu trả lời posix. Trong một số thử nghiệm thời gian thô sơ, casephương pháp này dường như là nhanh nhất trong ba phương pháp trên máy tính x86 32 bit khá cũ. Cả ba đều xa hiệu quả hơn một ví dụ đơn giản mà đường ống để một bộ xử lý stdin chia hai như: echo $var | cut -c1. Phân tích của tôi khá cơ bản dựa trên 10.000.000 lần lặp chỉ trên một máy tính / os - YMMV. Tôi chỉ sử dụng máy tính chậm hơn đó để phóng đại bất kỳ sự khác biệt nào và làm cho chúng rõ hơn - ít nhất là trên một nền tảng đó.
Juan

BTW, với 10.000.000 lần lặp đó, các phương thức dựng sẵn được mô tả trong câu trả lời này đã chạy trong khoảng một phút (trên hộp chậm nói trên). Các ống để cuthương vị mất hơn 5 giờ.
Juan

Điều gì sẽ xảy ra nếu bạn muốn tìm mọi thứ bắt đầu với "
Justin

5

Tôi biết điều này có thể là dị giáo, nhưng đối với những thứ này, tôi thà sử dụng grep hoặc egrep hơn là thực hiện nó từ trong vỏ. Nó tốn kém hơn một chút (tôi đoán vậy) nhưng đối với tôi giải pháp dễ đọc này bù đắp cho điều đó. Tất nhiên, đó là vấn đề sở thích cá nhân.

Vì thế:

myvar="   #comment asfasfasdf"
if ! echo $myvar | egrep -q '^ *#'
then
  echo "not a comment"
else
  echo "commented out"
fi

Nó hoạt động có hoặc không có không gian hàng đầu. Nếu bạn cũng muốn tính đến các tab hàng đầu, hãy sử dụng egrep -q '^ [\ t] * #' để thay thế.


Nghĩ về nó có lẽ tôi chỉ thích egrep vì tôi thích regexes, nhưng tôi coi grep / egrep là hữu ích trong việc sắp xếp các tình huống rộng hơn.
Eduardo Ivanec

0

Đây là một cách khác ...

# assign to var the value of argument actual invocation
var=${1-"#default string"}

if [[ "$var" == "#"* ]]
then
  echo "$var starts with a #"
fi

Chỉ cần sao chép dán nội dung vào một tệp, cấp quyền thực thi và xem cách nó hoạt động;).

Hy vọng nó giúp!

Lời chào hỏi.


1
Đó là bashism, nhưng thẻ là về "shell" chứ không phải "bash" :(.
pevik
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.