Jak podzielić jeden ciąg na wiele zmiennych w powłoce bash? [duplikat]

To pytanie ma już odpowiedź tutaj:

Szukałem rozwiązania i znalazłem podobne pytania, tylko próbowali podzielić zdania ze spacjami między nimi, a odpowiedzi nie pasują do mojej sytuacji.

Obecnie zmienna jest ustawiana na something a string like this:
ABCDE-123456
i chciałbym podzielić to na 2 zmienne, jednocześnie eliminując "-". tj.:
var1=ABCDE
var2=123456

Jak to możliwe?

To jest rozwiązanie, które zadziałało dla mnie:
var1=$(echo $STR | cut -f1 -d-)
var2=$(echo $STR | cut -f2 -d-)

Czy jest możliwe użycie polecenia cut , które będzie działać bez ogranicznika (każdy znak jest ustawiany jako zmienna)?

var1=$(echo $STR | cut -f1 -d?)
var2=$(echo $STR | cut -f1 -d?)
var3=$(echo $STR | cut -f1 -d?)
etc.

Author: crunchybutternut, 2012-05-09

6 answers

Jeśli twoje rozwiązanie nie musi być ogólne, tzn. musi działać tylko dla ciągów takich jak twój przykład, możesz to zrobić:

var1=$(echo $STR | cut -f1 -d-)
var2=$(echo $STR | cut -f2 -d-)

Wybrałem cut tutaj, ponieważ można po prostu rozszerzyć Kod o kilka dodatkowych zmiennych...

 119
Author: Rob I,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-09 17:00:36

read z {[5] } są do tego idealne:

$ IFS=- read var1 var2 <<< ABCDE-123456
$ echo "$var1"
ABCDE
$ echo "$var2"
123456

Edit:

Oto jak można odczytać poszczególne znaki w elementach tablicy:

$ read -a foo <<<"$(echo "ABCDE-123456" | sed 's/./& /g')"

Zrzuć tablicę:

$ declare -p foo
declare -a foo='([0]="A" [1]="B" [2]="C" [3]="D" [4]="E" [5]="-" [6]="1" [7]="2" [8]="3" [9]="4" [10]="5" [11]="6")'

Jeśli w łańcuchu są spacje:

$ IFS=$'\v' read -a foo <<<"$(echo "ABCDE 123456" | sed 's/./&\v/g')"
$ declare -p foo
declare -a foo='([0]="A" [1]="B" [2]="C" [3]="D" [4]="E" [5]=" " [6]="1" [7]="2" [8]="3" [9]="4" [10]="5" [11]="6")'
 139
Author: Dennis Williamson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-04 16:14:23

Jeśli wiesz, że będą to tylko dwa pola, możesz pominąć dodatkowe podprocesy w następujący sposób:

var1=${STR%-*}
var2=${STR#*-}

Co to robi? ${STR%-*} usuwa najkrótszy podłańcuch $STR pasujący do wzorca -* rozpoczynającego się od końca łańcucha. ${STR#*-} robi to samo, ale ze wzorem *- i zaczyna się od początku łańcucha. Każdy z nich ma odpowiedniki %% i ##, które znajdują najdłuższy zakotwiczony wzór. Jeśli ktoś ma pomocny mnemonic do zapamiętania co robi co, daj mi znać! Zawsze staram się pamiętać o obu.

 121
Author: mkb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-09 17:29:44

Brzmi jak praca dla {[1] } z niestandardowym IFS.

IFS=-
set $STR
var1=$1
var2=$2

(będziesz chciał to zrobić w funkcji z local IFS, aby nie zepsuć innych części skryptu, w których potrzebujesz IFS, aby być tym, czego oczekujesz.)

 33
Author: tripleee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-09 17:57:58

Korzystanie z funkcji regex bash:

re="^([^-]+)-(.*)$"
[[ "ABCDE-123456" =~ $re ]] && var1="${BASH_REMATCH[1]}" && var2="${BASH_REMATCH[2]}"
echo $var1
echo $var2

Wyjście

ABCDE
123456
 20
Author: anubhava,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-09 17:09:48
string="ABCDE-123456"
IFS=- # use "local IFS=-" inside the function
set $string
echo $1 # >>> ABCDE
echo $2 # >>> 123456
 15
Author: Archibald,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-12 11:03:29