我想读取一个文件并将其保存在变量中,但我需要保留变量而不仅仅是打印出文件。 我该怎么做呢?我已经写了这个脚本,但它不是我所需要的:

#!/bin/sh
while read LINE  
do  
  echo $LINE  
done <$1  
echo 11111-----------  
echo $LINE  

在我的脚本中,我可以将文件名作为参数,因此,如果文件包含“aaaa”,例如,它将打印出以下内容:

aaaa
11111-----

但这只是将文件打印到屏幕上,我想将它保存到一个变量中! 有什么简单的方法吗?


当前回答

正如Ciro Santilli指出的,使用命令替换将删除尾随换行符。他们添加尾随字符的变通方法很棒,但在使用了相当长的一段时间后,我决定需要一个根本不使用命令替换的解决方案。

我的方法现在使用read和printf内置的-v标志,以便将stdin的内容直接读入一个变量。

# Reads stdin into a variable, accounting for trailing newlines. Avoids
# needing a subshell or command substitution.
# Note that NUL bytes are still unsupported, as Bash variables don't allow NULs.
# See https://stackoverflow.com/a/22607352/113632
read_input() {
  # Use unusual variable names to avoid colliding with a variable name
  # the user might pass in (notably "contents")
  : "${1:?Must provide a variable to read into}"
  if [[ "$1" == '_line' || "$1" == '_contents' ]]; then
    echo "Cannot store contents to $1, use a different name." >&2
    return 1
  fi

  local _line _contents=()
   while IFS='' read -r _line; do
     _contents+=("$_line"$'\n')
   done
   # include $_line once more to capture any content after the last newline
   printf -v "$1" '%s' "${_contents[@]}" "$_line"
}

它支持带或不带换行符的输入。

使用示例:

$ read_input file_contents < /tmp/file
# $file_contents now contains the contents of /tmp/file

其他回答

我使用:

NGINX_PID=`cat -s "/sdcard/server/nginx/logs/nginx.pid" 2>/dev/null`

if [ "$NGINX_PID" = "" ]; then
  echo "..."
  exit
fi

如果你想把整个文件读入一个变量:

#!/bin/bash
value=`cat sources.xml`
echo $value

如果你想逐行阅读:

while read line; do    
    echo $line    
done < file.txt

在跨平台中,使用最低公分母sh:

#!/bin/sh
value=`cat config.txt`
echo "$value"

在bash或zsh中,在不调用cat的情况下将整个文件读入变量:

#!/bin/bash
value=$(<config.txt)
echo "$value"

在bash或zsh中调用cat来获取文件将被认为是无用的使用cat。

注意,没有必要为命令替换加上引号来保留换行符。

参见:Bash黑客的Wiki -命令替换-专长。

你可以通过for循环一次访问一行

#!/bin/bash -eu

#This script prints contents of /etc/passwd line by line

FILENAME='/etc/passwd'
I=0
for LN in $(cat $FILENAME)
do
    echo "Line number $((I++)) -->  $LN"
done

将整个内容复制到File(比如line.sh);执行

chmod +x line.sh
./line.sh

所有给定的解都非常慢,所以:

mapfile -d '' content </etc/passwd  # Read file into an array
content="${content[*]%$'\n'}"       # Remove trailing newline

更好地优化它,但我不能想到太多

更新:找到一个更快的方法

read -rd '' content </etc/passwd

这将返回退出代码1,所以如果你需要它 总是0:

read -rd '' content </etc/passwd || :