'IFS' là gì?


Câu trả lời:


17

IFSlà viết tắt của - đó là một ký tự phân tách các trường. Trong ví dụ bạn đã đăng, nó được đặt thành ký tự dòng mới ( ); Vì vậy, sau khi bạn đặt nó, sẽ xử lý từng dòng văn bản. Trong ví dụ đó, bạn có thể thay đổi giá trị của (thành một số chữ cái mà bạn có trong tệp đầu vào của mình) và kiểm tra xem văn bản sẽ được phân chia như thế nào.Input Internal Field Separator\nforIFS

BTW, từ câu trả lời bạn đã đăng giải pháp thứ hai là khuyến nghị ...

Như @jasonwryan nhận thấy, không phải Inputvậy Internal. Tên Inputđến từ awkđó cũng có OFS- Output Field Separator.


1
Lưu ý rằng IFS cũng được sử dụng để kết hợp các tham số cho đầu ra. Từ trang bash man: "Khi mở rộng xảy ra trong dấu ngoặc kép, nó sẽ mở rộng thành một từ duy nhất với giá trị của từng tham số được phân tách bằng ký tự đầu tiên của biến đặc biệt IFS."
Eric

Người ta cũng cần lưu ý rằng trong khi đó Slà cho dải phân cách trong vỏ Bourne nơi nó có nguồn gốc. Trong vỏ Korn và hầu hết các vỏ giống Bourne khác như đã được chỉ định bởi POSIX, phần Sdành cho Delimiter (chỉ kéo dài trí tưởng tượng của bạn một chút) như A::B:ví dụ được chia thành "A", "" và "B" (không có thêm ""). Đó là khác biệt so với awk's FShoặc scờ mở rộng tham số của zsh.
Stéphane Chazelas

27

IFSkhông liên quan trực tiếp đến việc lặp, nó liên quan đến việc tách từ. IFSgián tiếp xác định làm thế nào đầu ra từ lệnh được chia thành các phần mà vòng lặp lặp lại.

Khi bạn có một thay thế biến không được bảo vệ $foohoặc thay thế lệnh $(foo), có hai trường hợp:

  • Nếu ngữ cảnh mong đợi một từ đơn, ví dụ: khi thay thế nằm giữa hai dấu ngoặc kép "$foo"hoặc trong một phép gán biến x=$foo, thì chuỗi kết quả từ sự thay thế được sử dụng như nguyên trạng.
  • Nếu bối cảnh mong đợi nhiều từ, đó là trường hợp hầu hết các lần, thì hai lần mở rộng tiếp theo được thực hiện trên chuỗi kết quả:
    • Chuỗi được chia thành các từ . Bất kỳ ký tự xuất hiện trong $IFSđược coi là một dấu tách từ. Ví dụ: IFS=":"; foo="12:34::78"; echo $fooin 12 34 ​ 78(có hai khoảng trắng giữa 3478, vì có một từ trống).
    • Mỗi từ được coi là một mẫu toàn cầu và được mở rộng thành một danh sách các tên tệp . Ví dụ, foo="*"; echo $fooin danh sách các tập tin trong thư mục hiện tại.

Đối với các vòng lặp, giống như nhiều bối cảnh khác, mong đợi một danh sách các từ. Vì thế

for x in $(foo); do 

phá vỡ các $(foo)từ và coi mỗi từ như một mô hình toàn cầu. Giá trị mặc định IFSkhông gian, tab và dòng mới , vì vậy nếu fooin ra hai dòng hello worldhowdysau đó thân vòng lặp được thực thi với x=hello, sau đó x=worldx=howdy. Nếu IFSđược thay đổi rõ ràng để chỉ chứa một dòng mới, thì vòng lặp được thực thi cho hello worldhowdy. Nếu IFSđược thay đổi để được o, sau đó vòng lặp được thực hiện cho hell, ​ w, rld​␤h(trong đó ​␤là một ký tự xuống dòng) và wdy.


Tại sao bạn lại đề cập "gián tiếp" trong "IFS indirectly determines how ..."?
αsнι

1
@ αғsнι IFS(trực tiếp) xác định cách đầu ra của sự thay thế lệnh được chia nhỏ, sau đó (gián tiếp) xác định những gì vòng lặp lặp lại.
Gilles 'SO- ngừng trở nên xấu xa'

5

Từ man bash

IFS Bộ tách trường nội bộ được sử dụng để phân tách từ sau khi mở rộng và để phân tách các dòng thành các từ bằng lệnh đọc dựng sẵn. Giá trị mặc định là "<dấu cách> <tab> <dòng mới>".

Đây là một trong những biến nội bộ của Bash. Nó xác định cách Bash nhận ra các trường hoặc ranh giới từ, khi nó diễn giải các chuỗi ký tự.

Mặc dù nó mặc định là khoảng trắng (dấu cách, tab và dòng mới), ví dụ, nó có thể được thay đổi để phân tích tệp dữ liệu được phân tách bằng dấu phẩy.

http://tldp.org/LDP/abs/html/iternalvariables.html


0

Ngoài các câu trả lời tuyệt vời trước đây, hãy để tôi thêm rằng IFS rất hữu ích để phân tích cú pháp hiệu quả và di động trong các trường hợp đơn giản kết hợp với tập hợp . Hiệu quả, vì tránh sử dụng các công cụ con và công cụ sinh sản như grep hoặc sed:

resolutions="640x480,320x240"
xIFS=$IFS
IFS=','
for res in $resolutions; do
    xxIFS=$IFS
    IFS='x'
    set -- $res
    width=$1
    height=$2
    # handle width and height
    IFS=$xxIFS
done;
IFS=$xIFS

Chỉ cần lưu ý rằng chúng ta cần lưu trữ và khôi phục giá trị trước đó của IFS để tránh các sự cố không mong muốn trong các phần khác của tập lệnh.

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.