Tôi đã đọc chủ đề này: Làm thế nào để lặp qua các dòng của một tập tin?
Là IFS
gì Và cách sử dụng của nó trong bối cảnh của for
-loops là gì?
Tôi đã đọc chủ đề này: Làm thế nào để lặp qua các dòng của một tập tin?
Là IFS
gì Và cách sử dụng của nó trong bối cảnh của for
-loops là gì?
Câu trả lời:
IFS
là 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
\n
for
IFS
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 Input
vậy Internal
. Tên Input
đến từ awk
đó cũng có OFS
- Output Field Separator
.
S
là 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 S
dà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 FS
hoặc s
cờ mở rộng tham số của zsh
.
IFS
không liên quan trực tiếp đến việc lặp, nó liên quan đến việc tách từ. IFS
giá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ệ $foo
hoặc thay thế lệnh $(foo)
, có hai trường hợ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.$IFS
được coi là một dấu tách từ. Ví dụ: IFS=":"; foo="12:34::78"; echo $foo
in 12 34 78
(có hai khoảng trắng giữa 34
và 78
, vì có một từ trống).foo="*"; echo $foo
in 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 IFS
là không gian, tab và dòng mới , vì vậy nếu foo
in ra hai dòng hello world
và howdy
sau đó thân vòng lặp được thực thi với x=hello
, sau đó x=world
và x=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 world
và howdy
. Nếu IFS
được thay đổi để được o
, sau đó vòng lặp được thực hiện cho hell
, w
, rldh
(trong đó 
là một ký tự xuống dòng) và wdy
.
"IFS indirectly determines how ..."
?
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.
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.
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.