Jeg vil lese en fil og lagre den i en variabel, men jeg må beholde variabelen og ikke bare skrive ut filen. Hvordan kan jeg gjøre dette? Jeg har skrevet dette skriptet, men det er ikke helt det jeg trengte:
#!/bin/sh
while read LINE
do
echo $LINE
done <$1
echo 11111-----------
echo $LINE
I skriptet mitt kan jeg gi filnavnet som en parameter, så hvis filen for eksempel inneholder "aaaa", vil den skrive ut dette:
aaaa
11111-----
Men dette skriver bare ut filen på skjermen, og jeg vil lagre den i en variabel! Er det en enkel måte å gjøre dette på?
På tvers av plattformer bruker du sh
som laveste fellesnevner:
#!/bin/sh
value=`cat config.txt`
echo "$value"
I bash
eller zsh
, for å lese en hel fil inn i en variabel uten å påkalle cat
:
#!/bin/bash
value=$(<config.txt)
echo "$value"
Å påkalle cat
i bash
eller zsh
for å slurpe en fil vil bli betraktet som en Unyttig bruk av Cat.
Merk at det ikke er nødvendig å sitere kommandosubstitusjonen for å bevare nye linjer.
Se: Bash Hacker's Wiki - Command substitution - Specialities.
**To viktige fallgruver
som ble ignorert av andre svar så langt:
Fjerning av etterfølgende ny linje fra kommandoekspansjon.
Dette er et problem for:
value="$(cat config.txt)"
typeløsninger, men ikke for lesebaserte
løsninger.
Kommandoutvidelse fjerner etterfølgende nye linjer:
S="$(printf "a\n")"
printf "$S" | od -tx1
Utganger:
0000000 61
0000001
Dette bryter med den naive metoden for å lese fra filer:
FILE="$(mktemp)"
printf "a\n\n" > "$FILE"
S="$(<"$FILE")"
printf "$S" | od -tx1
rm "$FILE"
POSIX-omgåelse: legg til et ekstra tegn til kommandoutvidelsen og fjern det senere:
S="$(cat $FILE; printf a)"
S="${S%a}"
printf "$S" | od -tx1
Utganger:
0000000 61 0a 0a
0000003
Nesten POSIX-løsning: ASCII-koding. Se nedenfor.
Fjerning av NUL-tegn.
Det finnes ingen fornuftig Bash-metode for å lagre NUL-tegn i variabler.
Dette påvirker både ekspansjon og les
løsninger, og jeg vet ikke noen god løsning for det.
Eksempel:
printf "a\0b" | od -tx1
S="$(printf "a\0b")"
printf "$S" | od -tx1
Utganger:
0000000 61 00 62
0000003
0000000 61 62
0000002
Ha, vår NUL er borte!
Løsninger:
ASCII-koding. Se nedenfor.
bruk bash-utvidelsen `$ " " literaler:
S=$"a\0b"
printf "$S" | od -tx1
Fungerer bare for literaler, så ikke nyttig for å lese fra filer.
Løsning for fallgruvene.
Lagre en uuencode base64-kodet versjon av filen i variabelen, og dekod før hver bruk:
FILE="$(mktemp)"
printf "a\0\n" > "$FILE"
S="$(uuencode -m "$FILE" /dev/stdout)"
uudecode -o /dev/stdout <(printf "$S") | od -tx1
rm "$FILE"
Output:
0000000 61 00 0a
0000003
uuencode og udecode er POSIX 7 men ikke i Ubuntu 12.04 som standard (sharutils
-pakken) ... Jeg ser ikke et POSIX 7-alternativ for bash-prosessen <()
substitusjonsutvidelse bortsett fra å skrive til en annen fil ...
Selvfølgelig er dette tregt og upraktisk, så jeg antar at det virkelige svaret er: ikke bruk Bash hvis inndatafilen kan inneholde NUL-tegn.