如何将文件读入shell中的variables?
我想读取一个文件并将其保存在variables中,但我需要保留该variables,而不是只打印出文件。 我该怎么做? 我已经写了这个脚本,但它不是我所需要的:
#!/bin/sh while read LINE do echo $LINE done <$1 echo 11111----------- echo $LINE
在我的脚本中,我可以将文件名作为参数,例如,如果文件包含“aaaa”,则会打印出以下内容:
aaaa 11111-----
但是这只是将文件打印到屏幕上,我想把它保存到一个variables! 有没有一个简单的方法来做到这一点?
在跨平台,最常见的分母你使用:
#!/bin/sh value=`cat config.txt` echo "$value"
在bash
或zsh
,将整个文件读入一个variables而不用调用cat
:
#!/bin/bash value=$(<config.txt) echo "$value"
在bash
或zsh
调用cat
来啜食一个文件将被认为是一个无用的猫 。
请注意,没有必要引用命令replace来保留换行符。
请参阅: Bash Hacker的Wiki – 命令replace – 专业 。
如果你想把整个文件读入一个variables:
#!/bin/bash value=`cat sources.xml` echo $value
如果你想逐行阅读:
while read line; do echo $line done < file.txt
两个重要的陷阱
到目前为止,其他答案都忽略了这一点:
- 从命令扩展中删除换行符
- 删除NUL字符
从命令扩展中删除换行符
这是一个问题:
value="$(cat config.txt)"
types的解决scheme,但不是基于read
的解决scheme
命令扩展删除尾随换行符:
S="$(printf "a\n")" printf "$S" | od -tx1
输出:
0000000 61 0000001
这打破了从文件阅读的天真的方法:
FILE="$(mktemp)" printf "a\n\n" > "$FILE" S="$(<"$FILE")" printf "$S" | od -tx1 rm "$FILE"
POSIX解决方法:在命令扩展中附加一个额外的字符,并在以后删除它:
S="$(cat $FILE; printf a)" S="${S%a}" printf "$S" | od -tx1
输出:
0000000 61 0a 0a 0000003
几乎POSIX解决方法:ASCII编码。 见下文。
删除NUL字符
没有理智的Bash方式来存储variables中的NUL字符 。
这会影响扩展和read
解决scheme,我不知道有什么好的解决方法。
例:
printf "a\0b" | od -tx1 S="$(printf "a\0b")" printf "$S" | od -tx1
输出:
0000000 61 00 62 0000003 0000000 61 62 0000002
哈,我们的NUL消失了!
解决方法:
-
ASCII编码。 见下文。
-
使用bash扩展
$""
文字:S=$"a\0b" printf "$S" | od -tx1
只适用于文字,所以没有用的文件阅读。
避免陷阱的解决方法
在variables中存储文件的uuencode base64编码版本,并在每次使用之前解码:
FILE="$(mktemp)" printf "a\0\n" > "$FILE" S="$(uuencode -m "$FILE" /dev/stdout)" uudecode -o /dev/stdout <(printf "$S") | od -tx1 rm "$FILE"
输出:
0000000 61 00 0a 0000003
uuencode和udecode是POSIX 7,但默认情况下不在Ubuntu 12.04( sharutils
软件包)…除了写入另一个文件,我没有看到POSIX 7替代bash进程的<()
replace扩展…
当然,这很慢,不方便,所以我想真正的答案是:如果input文件可能包含NUL字符,则不要使用Bash。