Bir dosyayı okumak ve değişkene kaydetmek istiyorum, ancak değişkeni tutmam ve sadece dosyayı yazdırmamam gerekiyor. Bunu nasıl yapabilirim? Bu betiği yazdım ama tam olarak ihtiyacım olan şey bu değil:
#!/bin/sh
while read LINE
do
echo $LINE
done <$1
echo 11111-----------
echo $LINE
Kodumda, dosya adını bir parametre olarak verebilirim, böylece dosya "aaaa" içeriyorsa, örneğin, bunu yazdıracaktır:
aaaa
11111-----
Ancak bu sadece dosyayı ekrana yazdırıyor ve ben bunu bir değişkene kaydetmek istiyorum! Bunu yapmanın kolay bir yolu var mı?
Çapraz platformda, en düşük ortak paydada sh
kullanırsınız:
#!/bin/sh
value=`cat config.txt`
echo "$value"
bashveya
zshiçinde,
cat` komutunu çağırmadan bir dosyanın tamamını bir değişkene okumak için:
#!/bin/bash
value=$(<config.txt)
echo "$value"
Bir dosyayı höpürdetmek için bash
veya zsh
içinde cat
çağırmak Useless Use of Cat olarak kabul edilir.
Yeni satırları korumak için komut ikamesini tırnak içine almanın gerekli olmadığını unutmayın.
İki önemli tuzak
Şimdiye kadar diğer cevaplar tarafından göz ardı edilen:
Komut genişlemesinden sondaki yeni satırın kaldırılması
Bu kurum için bir sorun:
value="$(cat config.txt)"
tipi çözümler için geçerlidir, ancak oku
tabanlı çözümler için geçerli değildir.
Komut genişletme sondaki yeni satırları kaldırır:
S="$(printf "a\n")"
printf "$S" | od -tx1
Çıkışlar:
0000000 61
0000001
Bu, dosyalardan okumanın naif yöntemini bozar:
FILE="$(mktemp)"
printf "a\n\n" > "$FILE"
S="$(<"$FILE")"
printf "$S" | od -tx1
rm "$FILE"
POSIX geçici çözümü: komut genişletmesine fazladan bir karakter ekleyin ve daha sonra kaldırın:
S="$(cat $FILE; printf a)"
S="${S%a}"
printf "$S" | od -tx1
Çıkışlar:
0000000 61 0a 0a
0000003
Neredeyse POSIX geçici çözümü: ASCII kodlaması. Aşağıya bakın.
NUL karakterinin kaldırılması
NUL karakterlerini değişkenlerde saklamak için aklı başında bir Bash yolu yoktur.
Bu hem genişletme hem de oku
çözümlerini etkiliyor ve bunun için iyi bir çözüm bilmiyorum.
Örnek:
printf "a\0b" | od -tx1
S="$(printf "a\0b")"
printf "$S" | od -tx1
Çıkışlar:
0000000 61 00 62
0000003
0000000 61 62
0000002
Ha, NUL'umuz gitti!
Geçici çözümler:
ASCII kodlaması. Aşağıya bakınız.
bash uzantısı $""
değişmezlerini kullanın:
S=$"a\0b"
printf "$S" | od -tx1
Yalnızca değişmezler için çalışır, bu nedenle dosyalardan okumak için kullanışlı değildir.
Tuzaklar için çözüm
Dosyanın uuencode base64 kodlu sürümünü değişkende saklayın ve her kullanımdan önce kodunu çözün:
FILE="$(mktemp)"
printf "a\0\n" > "$FILE"
S="$(uuencode -m "$FILE" /dev/stdout)"
uudecode -o /dev/stdout <(printf "$S") | od -tx1
rm "$FILE"
Çıktı:
0000000 61 00 0a
0000003
uuencode ve udecode POSIX 7'dir ancak Ubuntu 12.04'te varsayılan olarak (sharutils
paketi) bulunmamaktadır... Başka bir dosyaya yazmak dışında bash işlemi <()
ikame uzantısı için bir POSIX 7 alternatifi göremiyorum...
Tabii ki, bu yavaş ve zahmetlidir, bu yüzden sanırım gerçek cevap şudur: girdi dosyası NUL karakterleri içerebiliyorsa Bash kullanmayın.