我是UNIX新手并且遇到了这个非常简单的问题:
我有一个文本文件(input.txt),每行包含一个字符串。它看起来像这样:
House
Monkey
Car
在我的shell脚本中,我需要逐行读取此输入文件以获取这样的变量:
things="House,Monkey,Car"
我知道这听起来很简单,但我找不到任何简单的解决方案。到目前为止我最接近的尝试:
#!/bin/sh
things=""
addToString() {
things="${things},$1"
}
while read line; do addToString $line ;done <input.txt
echo $things
但这不会奏效。关于我的谷歌研究,我认为while循环会创建一个新的子shell,但我错了(见评论部分)。然而,变量&#34;事物&#34;以后在回声中仍然没有。 (我不能只在while循环中写回声,因为我需要稍后使用该字符串)
你能帮帮我吗?任何帮助将不胜感激,谢谢!答案 0 :(得分:1)
这不是 shell 解决方案,但事实是纯shell中的解决方案通常过长且冗长。所以例如要进行字符串处理,最好使用属于“默认”Unix环境的特殊工具。
sed ':b;N;$!bb;s/\n/,/g' < input.txt
如果你想省略空行,那么:
sed ':b;N;$!bb;s/\n\n*/,/g' < input.txt
说到你的解决方案,它应该可行,但你应该总是在适用的地方使用引号。例如。这对我有用:
things=""
while read line; do things="$things,$line"; done < input.txt
echo "$things"
(当然,此代码存在问题,因为它会输出一个前导逗号。如果您想跳过空行,只需添加if
项检查。)
答案 1 :(得分:1)
你提出的建议工作正常!我在这里只做了两处修改:添加缺少的引号,并处理空字符串的情况。
things=""
addToString() {
if [ -n "$things" ]; then
things="${things},$1"
else
things="$1"
fi
}
while read -r line; do addToString "$line"; done <input.txt
echo "$things"
如果你管道进入while read
,这会创建一个子shell,这会占用你的变量。你没有管道 - 你正在进行<input.txt
重定向。没有子shell,代码无需更改即可运行。
也就是说,有更好的方法可以将项目列表读入shell变量。在3.0之后的任何版本的bash:
IFS=$'\n' read -r -d '' -a things <input.txt # read into an array
printf -v things_str '%s,' "${things[@]}" # write array to a comma-separated string
echo "${things_str%,}" # print that string w/o trailing comma
...在bash 4上,第一行可以是:
readarray -t things <input.txt # read into an array
答案 2 :(得分:0)
这可能/可能不起作用,具体取决于您使用的shell。在我的Ubuntu 14.04 / x64上,它适用于bash
和dash
。
为了使其更可靠并且独立于shell的行为,您可以尝试使用()
明确地将整个块放入子shell中。例如:
(
things=""
addToString() {
things="${things},$1"
}
while read line; do addToString $line ;done
echo $things
) < input.txt
P.S。你可以使用这样的东西来避免初始逗号。没有bash扩展(使用短路逻辑运算符而不是if
来表示简短性):
test -z "$things" && things="$1" || things="${things},${1}"
或使用bash扩展程序:
things="${things}${things:+,}${1}"
P.P.S。我该怎么做:
tr '\n' ',' < input.txt | sed 's!,$!\n!'
答案 3 :(得分:0)
您也可以这样做:
#!/bin/bash
while read -r i
do
[[ $things == "" ]] && things="$i" || things="$things","$i"
done < <(grep . input.txt)
echo "$things"
输出:
House,Monkey,Car
N.B:
使用grep
来处理空行以及文件末尾没有换行的可能性。 (如果文件末尾没有换行符,则普通while read
将无法读取最后一行。)