简体   繁体   English

如何在bash中间接分配变量以从Standard In,File和执行输出中获取多行数据

[英]How do I indirectly assign a variable in bash to take multi-line data from both Standard In, a File, and the output of execution

I have found many snippets here and in other places that answer parts of this question. 我在这里和其他地方发现了许多片段,可以回答部分问题。 I have even managed to do this in many steps in an inefficient manner. 我什至设法以低效的方式分多个步骤进行了此操作。 If it is possible, I would really like to find single lines of execution that will perform this task , rather than having to assign to a variable and copy it a few times to perform the task. 如果可能的话, 我真的很想找到可以执行此任务的单行执行 ,而不必分配给变量并复制几次以执行任务。

eg 例如

executeToVar ()
{
    # Takes Arg1: NAME OF VARIABLE TO STORE IN
    # All Remaining Arguments Are Executed
    local STORE_INvar="${1}" ; shift
    eval ${STORE_INvar}=\""$( "$@" 2>&1 )"\"
}

Overall does work, ie $ executeToVar SOME_VAR ls -l * # will actually fill SOME_VAR with the output of the execution of the ls -l * command that is taken from the rest of the arguments. 总体上是可行的,即$ executeToVar SOME_VAR ls -l * #实际上SOME_VAR使用从其余参数中获取的ls -l *命令的执行输出来填充SOME_VAR However, if the command was to output empty lines at the end, (for eg - echo -e -n '\\n\\n123\\n456\\n789\\n\\n' which should have 2 x new lines at the start and the end ) these are stripped by bash's sub-execution process. 但是,如果命令要在末尾输出空行,(例如- echo -e -n '\\n\\n123\\n456\\n789\\n\\n'在开始和结束处应该有2 x新行)会被bash的子执行过程剥离。 I have seen in other posts similar to this that this has been solved by adding a token 'x' to the end of the stream, eg turning the sub-execution into something like: 我在类似的其他帖子中看到,已通过在流的末尾添加标记'x'来解决此问题,例如将子执行变成类似以下内容:

eval ${STORE_INvar}=\""$( "$@" 2>&1 ; echo -n x )"\" # <-- ( Add echo -n x )
# and then if it wasn't an indirect reference to a var:
STORE_INvar=${STORE_INvar%x} 
# However no matter how much I play with:
eval "${STORE_INvar}"=\""${STORE_INvar%x}"\"  
# I am unable to indirectly remove the x from the end.

Anyway, I also need 2 x other variants on this, one that assigns the STDIN stream to the var and one that assigns the contents of a file to the var which I assume will be variations of this involving $( cat ${1} ) , or maybe $( cat ${1:--} ) to give me a '-' if no filename. 无论如何,我还需要2个其他变体,一个将STDIN stream分配给var,另一个将文件内容分配给var,我认为这是涉及$( cat ${1} ) ,或者$( cat ${1:--} )给我一个'-'(如果没有文件名)。 But, none of that will work until I can sort out the removal of the x that is needed to ensure accurate assignment of multi line variables. 但是,所有这些都将无法正常工作,直到我可以确定需要删除的x以确保准确分配多行变量为止。

I have also tried (but to no avail): 我也尝试过(但无济于事):

IFS='' read -d '' "${STORE_INvar}" <<<"$( $@ ; echo -n x )"
eval \"'${STORE_INvar}=${!STORE_INvar%x}'\"

This is close to optimal -- but drop the eval . 这接近最佳值,但会降低eval

executeToVar() { local varName=$1; shift; printf -v "$1" %s "$("$@")"; }

The one problem this formulation still has is that $() strips trailing newlines. 该公式仍然存在的一个问题是$()删除尾随的换行符。 If you want to prevent that, you need to add your own trailing character inside the subshell, and strip it off yourself. 如果要防止这种情况,则需要在子外壳中添加自己的尾随字符,然后自己删除它。

executeToVar() {
  local varName=$1; shift;
  local val="$(printf %s x; "$@"; printf %s x)"; val=${val#x}
  printf -v "$varName" %s "${val%x}"
}

If you want to read all content from stdin into a variable, this is particularly easy: 如果要将所有内容从stdin读取到变量中,这特别容易:

# This requires bash 4.1 for automatic fd allocation
readToVar() {
  if [[ $2 && $2 != "-" ]]; then
    exec {read_in_fd}<"$2"              # copy from named file
  else
    exec {read_in_fd}<&0                # copy from stdin
  fi
  IFS= read -r -d '' "$1" <&$read_in_fd # read from the FD
  exec {read_in_fd}<&-                  # close that FD
}

...used as: ...用作:

readToVar var < <( : "run something here to read its output byte-for-byte" )

...or... ...要么...

readToVar var filename

Testing these: 测试这些:

bash3-3.2$ executeToVar var printf '\n\n123\n456\n789\n\n'
bash3-3.2$ declare -p var
declare -- var="

123
456
789

"

...and... ...和...

bash4-4.3$ readToVar var2 < <(printf '\n\n123\n456\n789\n\n')
bash4-4.3$ declare -p var2
declare -- var2="

123
456
789

"

what'w wrong with storing in a file: 存储在文件中怎么了:

   $ stuffToFile filename $(stuff)

where "stuffToFile" tests for a. 其中“ stuffToFile”测试一个。 > 1 argument, b. > 1个参数,b。 input on a pipe 在管道上输入

   $ ... commands ... | stuffToFile filename   

and

   $ stuffToFile filename < another_file

where "stoffToFile" is a function: 其中“ stoffToFile”是一个函数:

function stuffToFile
{
    [[ -f $1 ]] || { echo $1 is not a file; return 1; }

    [[ $# -lt 2 ]] && { cat - > $1; return; }

    echo "$*" > $1
}

so, if "stuff" has leading and trailing blank lines, then you must: 因此,如果“材料”具有空白行的开头和结尾,那么您必须:

   $ stuff | stuffToFile filename

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将多行 bash 代码粘贴到终端并一次运行它? - How do I paste multi-line bash codes into terminal and run it all at once? 从具有多行记录的日志文件中提取数据到 CSV - Extracting data from a log file with multi-line records to CSV 如何从多行文件中读取变量? - How to read in variables from multi-line file? 如何将 grep 特定错误及其来自日志文件的多行描述和 output 它放在 Linux 的新日志文件中? - How to grep specific errors together with its multi-line description from a log file and output it in a new logfile in Linux? 如何在Bash中标识多行字符串中的目录路径,并用对自己文件内容的引用替换? - How to identify directory paths within multi-line string, replace with references to own file content, in Bash? 我如何在bash循环中从文件分配这些配置变量 - how do i assign these config variables from file in a bash loop 如何让我的 python 脚本连续将 output 的数据打印到行限制文本文件而不是标准终端? - How do I get my python script that continuously prints out data to output to a line limited text file instead of the standard terminal? 如何使用sed或Perl删除多行块中的部分行? - How do I remove part of a line in a multi-line chunk using sed or Perl? 如何使用 bash 将带有参数的 function 的 output 分配给变量? - How can I assign the output of a function with parameters to a variable using bash? 如何在UNIX中将AWK的多行输出插入到数组 - How to insert multi-line output of AWK to Array in UNIX
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM