Mogę mieć coś absolutnie nie tak, ale wydaje mi się to przekonujące, że ustawienie IFS jako jednego z poleceń na liście zadań do wykonania / wykonania nie ma absolutnie żadnego efektu.
Zewnętrzny IFS (poza while
konstrukcją) dominuje we wszystkich przykładach pokazanych w skrypcie poniżej.
Co tu się dzieje? Czy mam błędne wyobrażenie o tym, co IFS robi w tej sytuacji? Spodziewałem się, że wyniki podziału tablicy będą takie, jak pokazano w kolumnie „oczekiwany”.
#!/bin/bash
xifs() { echo -n "$(echo -n "$IFS" | xxd -p)"; } # allow for null $IFS
show() { x=($1)
echo -ne " (${#x[@]})\t |"
for ((j=0;j<${#x[@]};j++)); do
echo -n "${x[j]}|"
done
echo -ne "\t"
xifs "$IFS"; echo
}
data="a b c"
echo -e "----- -- -- \t --------\tactual"
echo -e "outside \t IFS \tinside"
echo -e "loop \t Field \tloop"
echo -e "IFS NR NF \t Split \tIFS (actual)"
echo -e "----- -- -- \t --------\t-----"
IFS=$' \t\n'; xifs "$IFS"; echo "$data" | while read; do echo -ne '\t 1'; show "$REPLY"; done
IFS=$' \t\n'; xifs "$IFS"; echo "$data" | while IFS= read; do echo -ne '\t 2'; show "$REPLY"; done
IFS=$' \t\n'; xifs "$IFS"; echo "$data" | while IFS=b read; do echo -ne '\t 3'; show "$REPLY"; done
IFS=" "; xifs "$IFS"; echo "$data" | while read; do echo -ne '\t 4'; show "$REPLY"; done
IFS=" "; xifs "$IFS"; echo "$data" | while IFS= read; do echo -ne '\t 5'; show "$REPLY"; done
IFS=" "; xifs "$IFS"; echo "$data" | while IFS=b read; do echo -ne '\t 6'; show "$REPLY"; done
IFS=; xifs "$IFS"; echo "$data" | while read; do echo -ne '\t 7'; show "$REPLY"; done
IFS=; xifs "$IFS"; echo "$data" | while IFS=" " read; do echo -ne '\t 8'; show "$REPLY"; done
IFS=; xifs "$IFS"; echo "$data" | while IFS=b read; do echo -ne '\t 9'; show "$REPLY"; done
IFS=b; xifs "$IFS"; echo "$data" | while IFS= read; do echo -ne '\t10'; show "$REPLY"; done
IFS=b; xifs "$IFS"; echo "$data" | while IFS=" " read; do echo -ne '\t11'; show "$REPLY"; done
echo -e "----- -- -- \t --------\t-----"
Wynik:
----- -- -- -------- actual
outside IFS inside assigned
loop Field loop # inner
IFS NR NF Split IFS # expected IFS
----- -- -- -------- ----- # --------- --------
20090a 1 (3) |a|b|c| 20090a #
20090a 2 (3) |a|b|c| 20090a # |a b c| IFS=
20090a 3 (3) |a|b|c| 20090a # |a | c| IFS=b
20 4 (3) |a|b|c| 20 #
20 5 (3) |a|b|c| 20 # |a b c IFS=
20 6 (3) |a|b|c| 20 # |a | c| IFS=b
7 (1) |a b c| #
8 (1) |a b c| # |a|b|c| IFS=" "
9 (1) |a b c| # |a | c| IFS=b
62 10 (2) |a | c| 62 # |a b c| IFS=
62 11 (2) |a | c| 62 # |a|b|c| IFS=" "
----- -- -- -------- ----- --------- -------
$IFS
są usuwane na początku / na końcu linii wprowadzania, tak przypuszczam? (Jak to działa.)a<tab>b
wread var
spowoduje var o wartościa<space>b
, ale jeśli zamiast maszIFS='<newline>' read var
wtedy wartość var będziea<tab>b
.Mówiąc prościej, musisz czytać więcej niż jedną zmienną na raz, aby
IFS=<something> read ...
konstrukcja miała widoczny efekt w twoich przykładach 1 .Brakuje zakresu
read
w przykładach. W testach nie ma modyfikacji IFS w pętli. Pozwólcie, że wskażę dokładnie, gdzie działa drugi IFS w każdej z twoich linii:Jest tak jak w przypadku każdego programu wykonanego w powłoce. Zmienna zdefiniowana (ponownie) w wierszu poleceń wpływa na wykonanie programu. I tylko to (ponieważ nie eksportujesz). Dlatego, aby skorzystać z przedefiniowania
IFS
w takim wierszu, musisz poprosićread
o przypisanie wartości do więcej niż jednej zmiennej . Spójrz na te przykłady:1 Jak właśnie dowiedziałem się od Gillesa , może być korzystne ustawienie
IFS=''
(puste) podczas odczytu tylko jednego pola: pozwala to uniknąć obcięcia białych znaków na początku linii.źródło
IFS= read
preferowane jest po prostu ponowne ustawienie zmiennej środowiskowej IFS”. Nie miałem wtedy świadomości, że zmienne lokalne mogą być ustawiane przez osobę wywołującą polecenie. To była odpowiedź na to pytanie. Z czasem rozwinęło się to, odnosząc się do głównej kwestii tego pytania, ale zanim zdałem sobie z tego sprawę, zadałem już to pytanie ... Być może dwa pytania są podobne do dwóchsed
pytań, więc czuję, że utrzymam to asis ... Więcej tytułów dla pracowników Google do Google.