如何在 Bash 中连接文件中的所有行?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8013140/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 01:01:45  来源:igfitidea点击:

How to concatenate all lines from a file in Bash?

bashshellloopswhile-loop

提问by Yugal Jindle

I have a file csv:

我有一个文件csv

data1,data2,data2
data3,data4,data5
data6,data7,data8

I want to convert it to (Contained in a variable):

我想将其转换为(包含在变量中):

variable=data1,data2,data2%0D%0Adata3,data4,data5%0D%0Adata6,data7,data8

variable=data1,data2,data2%0D%0Adata3,data4,data5%0D%0Adata6,data7,data8

My attempt :

我的尝试:

data=''
cat csv | while read line
do
data="${data}%0D%0A${line}"
done
echo $data  # Fails, since data remains empty (loop emulates a sub-shell and looses data)

Please help..

请帮忙..

回答by Marc B

Simpler to just strip newlines from the file:

从文件中删除换行符更简单:

tr '\n' '' < yourfile.txt > concatfile.txt

回答by Andrew Schulman

In bash,

在 bash 中,

data=$(
while read line
do
  echo -n "%0D%0A${line}"
done < csv)

In non-bash shells, you can use `...`instead of $(...). Also, echo -n, which suppresses the newline, is unfortunately not completely portable, but again this will work in bash.

在非 bash shell 中,您可以使用`...`代替$(...). 此外,echo -n,抑制换行符,不幸的是不是完全可移植的,但这同样适用于 bash。

回答by sorpigal

Some of these answers are incredibly complicated. How about this.

其中一些答案非常复杂。这个怎么样。

 data="$(xargs printf ',%s' < csv | cut -b 2-)"

or

或者

 data="$(tr '\n' ',' < csv | cut -b 2-)"

Too "external utility" for you?

对你来说太“外部效用”了吗?

IFS=$'\n', read -d'
data="$(tr ' ' , <<<"${data[@]}")"
' -a data < csv

Now you have an array! Output it however you like, perhaps with

现在你有了一个数组!随心所欲地输出它,也许用

data="$(printf "${data[0]}" ; printf ',%s' "${data[@]:1:${#data}}")"

Still too "external utility?" Well fine,

还是太“外在效用”?好吧,

data="$(echo -n "${data[0]}" ; for d in "${data[@]:1:${#data[@]}}" ; do echo -n ,"$d" ; done)"

Yes, printfcan be a builtin. If it isn't but your echois and it supports -n, use echo -ninstead:

是的,printf可以是内置的。如果不是,但您echo是并且它支持-n,请echo -n改用:

for line in $(cat file.txt); do echo -n $line; done

Okay, now I admit that I am getting a bit silly. Andrew's answer is perfectly correct.

好吧,现在我承认我有点傻了。安德鲁的回答是完全正确的。

回答by Alexandre Mélard

I would much prefer a loop:

我更喜欢循环:

variable=$(
  RS=""
  while read line; do
    printf "%s%s" "$RS" "$line"
    RS='%0D%0A'
  done < filename
)

Note: This solution requires the input file to have a new line at the end of the file or it will drop the last line.

注意:此解决方案要求输入文件在文件末尾有一个新行,否则会删除最后一行。

回答by glenn Hymanman

Another short bash solution

另一个简短的 bash 解决方案

awk 'END { print r }
{ r = r ? r OFS 
data=

while IFS= read -r; do
  [ -n "$data" ] &&
     data=$data%0D%0A$REPLY ||
    data=$REPLY
done < infile

printf '%s\n' "$data"   
:
data=

while IFS= read -r; do
  [[ -n $data ]] &&
     data+=%0D%0A$REPLY ||
    data=$REPLY
done < infile

printf '%s\n' "$data"
} ' OFS='%0D%0A' infile

回答by Dimitre Radoulov

while read line; do 
 # ...
done < csv

With shell:

随着

output=$(echo $(cat ./myFile.txt) | sed 's/ /%0D%0A/g')

Recent bashversions:

最近的bash版本:

##代码##

回答by themel

Useless use of cat, punished! You want to feed the CSV into the loop

用猫没用,受罚!您想将 CSV 输入循环

##代码##

回答by BiS

A very simple single-line solution which requires no extra files as its quite easy to understand (I think, just cat the file together and perform sed-replace):

一个非常简单的单行解决方案,不需要额外的文件,因为它很容易理解(我认为,只需将文件放在一起并执行 sed-replace):

##代码##