Minulla on tiedosto.txt, joka minun täytyy lukea Bash-taulukoksi. Sitten minun on poistettava välilyönnit, lainausmerkit ja kaikki paitsi ensimmäinen pilkku jokaisesta merkinnästä . Tässä kuinka pitkälle olen päässyt:
$ cat file.txt 10,this 2 0 , i s 30,"all" 40,I 50,n,e,e,d,2 60",s e,e" $ cat script.sh #!/bin/bash readarray -t ARRAY<$1 ARRAY=( "${ARRAY[@]// /}" ) ARRAY=( "${ARRAY[@]//\"/}" ) for ELEMENT in "${ARRAY[@]}";do echo "|ELEMENT|$ELEMENT|" done $ ./script.sh file.txt |ELEMENT|10,this| |ELEMENT|20,is| |ELEMENT|30,all| |ELEMENT|40,I| |ELEMENT|50,n,e,e,d,2| |ELEMENT|60,se,e|
Mikä toimii hyvin pilkkuja lukuun ottamatta. Olen tietoinen siitä, että on olemassa useita tapoja nylkeä tämä kissa, mutta suuremman komentosarjan vuoksi tämä on osa, haluaisin todella käyttää parametrien korvaamista päästäksesi tänne:
|ELEMENT|10,this| |ELEMENT|20,is| |ELEMENT|30,all| |ELEMENT|40,I| |ELEMENT|50,need2| |ELEMENT|60,see|
Onko tämä mahdollista parametrien korvaamisen avulla?
Kommentit
- Onko sinun syytä pitää teksti taulukkoa ja miksi ’ ei saa antaa esim.
awk
taised
käsittelevätkö tietoja? - @Jeff – Taulukon silmukkaaminen on painajainen, joka toteutetaan suuremmassa komentosarjassa, ’ m työskentelen.
- @JonRed En tiedä mitä ’ teet, joten ’ on täysin mahdollista, että sinulla ei ehkä ole valinnanvaraa asiassa, mutta yleensä, kun huomaat harrastavansi niin monimutkaista merkkijonoakrobatiaa kuoressa, että ’ on erittäin hyvä osoitus siitä, että sinun tulisi käyttää todellista ohjelmointikieliä. Kuorta ei ole suunniteltu ohjelmointikieleksi, ja vaikka sitä voidaan käyttää yhtenä, se ei todellakaan ole ’ t hyvä idea monimutkaisemmille asioille. Kehotan teitä harkitsemaan vaihtamista perl-, python- tai mihin tahansa muuhun komentosarjakieleen.
- @terdon It ’ on hauskaa, sain vain sanoa melkein tarkan sama asia kollegalleni ennen kuin luin tämän viestin. Sanoin pohjimmiltaan, että tämä on tämän komentosarjan lopullinen versio ja että kaikki uudet vaatimukset edellyttävät uudelleen kirjoittamista Perliin. Joten kyllä, olen ehdottomasti samaa mieltä
vastaus
Poistaisin poistettavat tiedot käyttämällä sed
ennen lataamista taulukkoon (huomioi myös pienten muuttujien nimet, yleensä on parasta välttää isoja kirjaimia muuttujista shell-komentosarjoissa):
#!/bin/bash readarray -t array< <(sed "s/"//g; s/ *//g; s/,/"/; s/,//g; s/"/,/" "$1") for element in "${array[@]}";do echo "|ELEMENT|$element|" done
Tämä tuottaa seuraavan tuloksen esimerkkitiedostoon:
$ foo.sh file |ELEMENT|10,this| |ELEMENT|20,is| |ELEMENT|30,all| |ELEMENT|40,I| |ELEMENT|50,need2| |ELEMENT|60,see|
Jos sinun on todella käytettävä parametria kokeile jotain tällaista:
#!/bin/bash readarray -t array< "$1" array=( "${array[@]// /}" ) array=( "${array[@]//\"/}" ) array=( "${array[@]/,/\"}" ) array=( "${array[@]//,/}" ) array=( "${array[@]/\"/,}" ) for element in "${array[@]}"; do echo "|ELEMENT|$element|" done
kommentit
Vastaa
Sikäli kuin näen, ei ole tarvetta luo se bash
-taulukkoon kyseisen tuotoksen luomiseksi:
$ sed "s/[ "]//g; s/,/ /; s/,//g; s/ /,/; s/.*/|ELEMENT|&|/" <file |ELEMENT|10,this| |ELEMENT|20,is| |ELEMENT|30,all| |ELEMENT|40,I| |ELEMENT|50,need2| |ELEMENT|60,see|
sed
-lauseke poistaa välilyönnit ja lainausmerkit, korvaa ensimmäisen pilkun välilyönnillä (merkkijonossa ei ole muita välilyöntejä tässä vaiheessa), poistaa kaikki muut pilkut, palauttaa ensimmäisen pilkun ja valmistelee ja liittää ylimääräiset tiedot .
Vaihtoehtoisesti GNU: lla sed
:
sed "s/[ "]//g; s/,//2g; s/.*/|ELEMENT|&|/" <file
(vakio sed
ei tue 2
– ja g
-yhdistelmää lipuina s
-komento).
Kommentit
- GNU sedin kanssa voit käyttää
's/,//2g
poistaa pilkkuja, alkaen toisesta - Ja viimeiset 2 s /// -komennot voivat olla
s/.*/|ELEMENT|&|/
mutta se voi olla enemmän vaivaa sedille. - @glennjackman Mahdollisesti, mutta se näyttää melko siistiltä.
- Joo, tämä on osa suurempaa komentosarjaa. Matriisi on välttämätön, ei vain lähtöä varten. Tästä syystä olen kiinnostunut parametrien korvaamisesta. Voisin silmukata taulukon yli tällä, mutta se on painajainen toteuttaa. Terndon toimitti silmukkavapaan ratkaisun käyttäen sed, että I ’ palaan todennäköisesti takaisin, jos parametrin korvaaminen on kiellettyä.
- Jos minua ei ollut ’ ei sidottu matriisiin, tämä olisi kuitenkin paras ratkaisu.
Vastaa
ELEMENT="50,n,e,e,d,2" IFS=, read -r first rest <<<"$ELEMENT" printf "%s,%s\n" "$first" "${rest//,/}"
50,need2
Poista ALLCAPS-muuttujien nimistä. Lopulta törmäät tärkeän ”järjestelmä” -muuttujan, kuten PATH, kanssa ja rikkot koodisi.
Kommentit
- Ei parametrien korvaamista. MUTTA, en tiennyt, että ALLCAPS-muuttujien nimet olivat huono tapa Bashissa. Teet hyvän asian, jonka päällekkäinen googling varmasti vahvistaa. Kiitos tyylini parantamisesta! 🙂
- Olen ’ vastannut kysymyksiin, joihin henkilö kirjoitti
PATH=something; ls $PATH
ja sitten ihmettelinls: command not found
-virhe. - Lähes sata sisäänrakennettua muuttujaa on nimetty kaikissa kirjaimissa (napsauta
tätä man-sivua linkki ) nähdäksesi …
Vastaa
[Tämä on pohjimmiltaan kehittyneempi versio glenn jackmannin vastauksesta ]
Assosiatiivisen taulukon rakentaminen irrotetusta avaimesta ja arvosta käyttämällä ensimmäistä pilkkua erottimena:
declare -A arr while IFS=, read -r k v; do arr["${k//[ \"]}"]="${v//[ ,\"]}"; done < file.txt for k in "${!arr[@]}"; do printf "|ELEMENT|%s,%s|\n" "$k" "${arr[$k]}" done |ELEMENT|20,is| |ELEMENT|10,this| |ELEMENT|50,need2| |ELEMENT|40,I| |ELEMENT|60,see| |ELEMENT|30,all|
vastaus
Voit siirtyä matriisin yli ja käyttää välimuuttujaa:
for((i=0; i < "${#ARRAY[@]}"; i++)) do rest="${ARRAY[i]#*,}" ARRAY[i]="${ARRAY[i]%%,*}","${rest//,/}" done
Tämä osoittaa rest
-osan ensimmäisen pilkun jälkeen; liitämme sitten kolme kappaletta takaisin alkuperäiseen muuttuja:
- ensimmäinen pilkku edeltävä osa
- pilkku
- jokaisen pilkun korvaaminen
rest
-kohdassa ilman mitään
kommentteja
- Tämä oli ensimmäinen ajatukseni ja se on tarpeeksi yksinkertainen esimerkkiä varten, mutta tämä on osa suurempaa komentosarjaa, jossa taulukko on massiivinen ja siellä ’ on jo silmukoita ja se olisi koko juttu. Tämä toimisi ehdottomasti, mutta olisi erittäin hankalaa toteuttaa suuremmassa projektissa, jonka parissa ’ työskentelen.
- Riittävän oikeudenmukainen; Yritin vain vastata rajoitusten puitteissa (vain parametrien laajentaminen).
RANDOMTEXTTHATWILLNEVERBEINTHEFILE
-tunnuksesi sijaan.