Đánh giá một chuỗi trong shell script


8

Tôi đang làm theo hướng dẫn kịch bản bash shell này:

Trong phần So sánh số, nó trích dẫn một ví dụ:

anny > num=`wc -l work.txt`

anny > echo $num
201

anny > if [ "$num" -gt "150" ]
More input> then echo ; echo "you've worked hard enough for today."
More input> echo ; fi

Điều dường như xảy ra ở trên là chúng ta lưu trữ một chuỗi các lệnh trong một biến bash và sau đó chúng ta gọi echo trên biến đó. Điều dường như xảy ra là chuỗi được ước tính và lệnh wc được thực thi và trả về số dòng cho thiết bị đầu cuối điều khiển.

Ok, vì vậy tôi khởi chạy thiết bị đầu cuối của mình trong Ubuntu 12.04 và thử một cái gì đó tương tự:

$ touch sample.txt && echo "Hello World" > sample.txt
$ cat sample.txt
Hello World
$ num='wc -l sample.txt'
echo $num
wc -l sample.txt

Đợi một chút, điều đó không đánh giá chuỗi và trả về số dòng. Điều đó chỉ lặp lại chuỗi trở lại thiết bị đầu cuối. Tại sao tôi nhận được kết quả khác nhau?


Lưu ý rằng num không bao giờ được gán chuỗi wc -l work.txt, thay vào đó, nó được gán số 201.
ignis

Câu trả lời:


2

Bạn cần sử dụng backticks để đánh giá biểu thức.

$ num=`wc -l sample.txt`
$ echo $num
1 sample.txt

Nếu bạn chỉ muốn thấy "1" trong đầu ra, hãy sử dụng lệnh

$ num=`cat sample.txt | wc -l`
$ echo $num
1

Và cũng hoạt động:

$ num=`wc -l < sample.txt`
$ echo $num
1

Để biết thêm thông tin, hãy xem Sự khác biệt giữa doublequote "", singlequote '' và backticks ơi ôn trên dòng lệnh?


Có ai biết tại sao tôi nhận được '1 sample.txt' không chỉ là số '1'?
JohnMerlino 17/03/2016

Đó là cách làm việc của wclệnh. Hãy thử cat sample.txt | wc -l.
Danatela

wc -l hiển thị số lượng dòng có trong một tệp cùng với tên tệp của nó.
Avinash Raj

5

Xin lưu ý rằng biểu tượng:

'

Trích dẫn duy nhất

   Enclosing characters in single quotes preserves the  literal  value  of
   each character within the quotes.  A single quote may not occur between
   single quotes, even when preceded by a backslash.

`

Backquote

   Command substitution allows the output of a command to replace the com
   mand name.  There are two forms:

          $(command)
   or
          `command`

   Bash performs the expansion by executing command and replacing the com
   mand  substitution  with  the  standard output of the command, with any
   trailing newlines deleted.

Vì vậy, Backquote đang trả kết quả của lệnh cho Đầu ra tiêu chuẩn. Đó là lý do tại sao

`wc -l sample.txt`

trả về kết quả của lệnh

'wc -l sample.txt'

chỉ cần trả về "wc -l sample.txt" như chuỗi thông thường

Hãy xem xét làm điều này như ví dụ:

$ A='wc -l /proc/mounts'
$ B=`wc -l /proc/mounts`
$ C=$(wc -l /proc/mounts)

Và bây giờ lặp lại cả ba biến:

$ echo $A
wc -l /proc/mounts
$ echo $B
35 /proc/mounts
$ echo $C
35 /proc/mounts

4

Nếu bạn muốn nắm bắt đầu ra của một lệnh trong một biến, bạn cần sử dụng backticks ``hoặc đặt lệnh trong $():

$ d=$(date)
$ echo "$d"
Mon Mar 17 10:22:25 CET 2014
$ d=`date`
$ echo "$d"
Mon Mar 17 10:22:25 CET 2014

Lưu ý rằng chuỗi thực sự được đánh giá tại thời điểm khai báo biến, không phải khi bạn lặp lại chuỗi. Lệnh thực sự được chạy trong $()hoặc backticks và đầu ra của lệnh đó được lưu dưới dạng giá trị của biến.

Nói chung, bạn nên luôn luôn sử dụng $()thay vì backticks bị phản đối và chỉ xung quanh vì lý do tương thích và hạn chế hơn nhiều. Bạn không thể, ví dụ, các lệnh lồng trong backticks nhưng bạn có thể với $():

$ echo $(date -d $(echo yesterday))
Sun Mar 16 10:26:07 CET 2014

Xem chủ đề này trên U & L để biết thêm chi tiết về lý do ``nên tránh.


1
Tôi đồng ý kịch bản nên thích $( )đến ` `. Nhưng như wag nói , backquote làm tổ. echo $(date -d $(echo yesterday))trở thành echo `date -d \`echo yesterday\``; echo $(echo $(date -d $(echo yesterday)))trở thành echo `echo \`date -d \\\`echo yesterday\\\`\``. Tôi nói điều này không bác bỏ luận điểm của bạn mà để củng cố nó : thoát khỏi các câu hỏi ngược nội bộ làm cho ` `cú pháp mạnh hơn thường được thừa nhận, nhưng cách đối xử đặc biệt \là kỳ lạ, đáng ngạc nhiên và khó lý luận. Với $( )những gì bạn thấy thường là những gì bạn nhận được.
Eliah Kagan
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.