Dòng lệnh: Trích xuất chuỗi con từ đầu ra


25

Nói tôi chạy lệnh SayStuff

$ SayStuff

và đầu ra là

Watermelons and cucumbers

Hiện nay. Nói rằng tôi muốn trích xuất chuỗi con cucumberstừ đầu ra và chuyển nó thành một cái gì đó.
Cách tôi sẽ đi về lập trình này sẽ là phân chia đầu ra thành một mảng bởi Dấu phân cách Space và tham chiếu nó theo ArrayName[2]. Tôi còn khá mới với các kịch bản shell và chỉ thành công trong việc đào sâu các cutví dụ bán mật mã , không có cái nào có ý nghĩa.

Có ý kiến ​​gì không?

Câu trả lời:


30
$ echo "Watermelons and cucumbers" | cut -d ' ' -f 3
cucumbers

Các -d ' 'kể cutđể phân chia trên không gian. -f 3chọn cột thứ ba.

Bạn cũng có thể sử dụng awk, mà không tách dựa trên không gian đã và làm cho các cột có sẵn như $1, $2, ...

$ echo "Watermelons and cucumbers" | awk '{ print $3 }'
cucumbers

Lưu ý rằng cutsẽ không xử lý một số lượng không gian khác nhau, trong khi awklàm.
Zitrax

13

Tôi có thể sẽ sử dụng một trong các tùy chọn đã được cung cấp bởi @slhck nhưng đây là một vài cách khác để làm điều này:

  1. Sử dụng mảng, như bạn làm trong bất kỳ ngôn ngữ nào khác:

    $ foo=( $(SayStuff) ) 
    $ echo ${foo[2]}
    cucumbers

    Các var=()tuyên bố một mảng, $(command)lưu đầu ra của lệnh. Vì vậy, foo=( $(SayStuff) )lưu trữ đầu ra của SayStuffmảng foovà yuou sau echođó là phần tử thứ ba với ${foo[2]}.

  2. sed

    $ SayStuff | sed 's/.* \(.*\)/\1/'
    cucumbers

    Các sedlệnh sẽ thay thế ( s///) tất cả mọi thứ với từ cuối cùng. Regex khớp với bất cứ thứ gì lên tới một khoảng trắng ( .*) sẽ khớp mọi thứ cho đến khoảng trống cuối cùng và sau đó ghi lại từ cuối cùng (\(.*\). Vì từ này đã bị bắt, chúng ta có thể gọi nó là \1.

    Một phiên bản đơn giản hơn:

    $ SayStuff | sed 's/.* //'
    cucumbers
  3. bash

    $ foo=$(SayStuff); echo ${foo##* } 
    cucumbers

    Điều này sử dụng khả năng thao tác chuỗi của bash, xem tại đây để biết thêm chi tiết.

  4. Bash nhiều hơn

    $ SayStuff | while read a b c; do echo $c; done
    cucumbers
  5. Perl, nơi tất nhiên, có nhiều cách để làm điều này:

    $ SayStuff | perl -lane 'print $F[$#F]'
    cucumber

    -alàm cho perlhành vi như awk, chia dòng ở khoảng trắng và lưu vào mảng @F. Sau đó chúng tôi in phần tử cuối cùng của @F( $#Flà số phần tử trong @F). Thông báo -lcho perl thêm một dòng mới vào mỗi printcâu lệnh, -nrằng nó sẽ xử lý dòng STDIN theo dòng và -enó sẽ chạy tập lệnh được đưa ra ở dòng lệnh.

    $ SayStuff | perl -pe 's/.* //'
    cucumber

    Các tùy chọn đã được giải thích ở trên, chúng tôi chỉ xóa mọi thứ cho đến không gian cuối cùng và in ( -p).

    $ perl -le 'print $ARGV[$#ARGV]' $(SayStuff)
    cucumbers

    Ở đây chúng ta chuyển qua Watermelons and cucumberslàm đối số, mà perl sẽ lưu trong @ARGmảng và do đó, chúng ta in phần tử cuối cùng của @ARG.

  6. mánh khóe. Cái này sử dụng sedđể chuyển đổi khoảng trắng thành dòng mới và sau đó tailchỉ in dòng cuối cùng.

    $ SayStuff | sed 's/ /\n/g' | tail -n 1
    cucumbers
  7. grep và biểu thức chính quy, sử dụng -ochỉ in chuỗi phù hợp.

    $ SayStuff | grep -Po '\w+$' 
    cucumbers
  8. gian lận

    $ SayStuff | grep -o cucumbers
    cucumbers

2

Dưới đây là một số giải thích thêm:

Usage: cut OPTION... [FILE]...

Print selected parts of lines from each FILE to standard output.

   -d, --delimiter=DELIM
          use DELIM instead of TAB for field delimiter

   -f, --fields=LIST
          select only these fields;  also print any line that contains  no
          delimiter character, unless the -s option is specified

Vì vậy, nếu bạn cần trường thứ 3 và nó được phân cách bằng dấu cách '' thì đó là

$ echo "Watermelons and cucumbers" | cut -d ' ' -f 3  
cucumbers

Nếu bạn muốn trường LAST có lẽ bạn nên sử dụng awk .
Trong trường hợp này, nó trở thành:

$ echo "Dưa hấu và dưa chuột" | awk '{print $ NF}'
dưa chuột

Trong awkNF là số trường trong dòng $NFcó nghĩa là trường cuối cùng trong dòng.


về cơ bản, câu hỏi tương tự cũng có ở đây nhưng khái quát hơn: stackoverflow.com/questions/3162385/
Kiếm
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.