使用 readarray 时如何避免数组元素后面出现换行符?

问题描述 投票:0回答:3

我有一个文本文件

Today, 12:34 
Today, 21:43 
Today, 12:43
https://123
https://456
https://789

并想将每一行打印到一个数组中。因此我使用:

readarray array <'file.txt'

现在我想创建一个新的数组混合日期和相应的链接,因此在本例中,第 1 行对应于第 4 行,依此类推。 我写了

declare -a array2
array2[0]=${array[0]}${array[3]}
array2[1]=${array[1]}${array[4]}
...

使用“echo ${array2[*]}”打印整个 array2 得到以下结果:

Today, 12:34
https://123
 Today, 21:43
https://456
 Today, 12:43
https://789

为什么元素之间有换行符,例如在 array2[0] 和 array2[1] 之间?我怎样才能摆脱它们呢? 为什么第二行及以下行中 T 之前有一个空格? 上面的代码是否可以循环编写?

亲切的问候, X3nion

arrays bash
3个回答
4
投票

使用

-t
参数来防止换行符包含在存储在各个数组元素中的数据中:

readarray -t array <file.txt

顺便说一句,您始终可以在事后删除换行符,即使您首先阻止它们被读取,通过使用

${var%suffix}
参数扩展和
$'\n'
语法来引用换行文字:

array2[0]=${array[0]%$'\n'}${array[3]%$'\n'}

1
投票

awk
解决方案会更简单(而且更快)。只需将包含
"Today"
的所有行读取到
awk
中的数组中即可。然后从不包含
"Today"
的行开始写入当前行,然后是数组中的关联行,例如

awk '/Today/{a[++n] = $0; next} {printf "%s\t%s\n", $0, a[++m]}' file.txt

示例使用/输出

使用

file.txt
中的示例行,您将收到:

$ awk '/Today/{a[++n] = $0; next} {printf "%s\t%s\n", $0, a[++m]}' file.txt
https://123     Today, 12:34
https://456     Today, 21:43
https://789     Today, 12:43

或者如果您想更改订单:

$ awk '/Today/{a[++n] = $0; next} {printf "%s\t%s\n", a[++m], $0}' file.txt
Today, 12:34    https://123
Today, 21:43    https://456
Today, 12:43    https://789

每条评论添加

如果您在使用

awk
的输出之前收到空格,那是因为第一个字段之前有空格。要消除空格,您可以强制
awk
重新计算每个字段,只需将字段设置为等于自身即可删除空格,例如

awk '{$1 = $1} /Today/{a[++n] = $0; next} {printf "%s\t%s\n", a[++m], $0}' file.txt

通过将第一个字段设置为等于其自身 (

$1 = $1
),您可以强制
awk
重新计算每个字段,从而消除前导空格。以带有前导空格的数据为例(每行前面有 3 个空格):

   Today, 12:34
   Today, 21:43
   Today, 12:43
   https://123
   https://456
   https://789

使用更新后的命令给出上面显示的答案,并删除空格。

使用

paste

您可以将

paste
命令与
wc -l
(字数统计行)命令一起用作另一个选项。只需确定行数,然后使用过程替换输出前 1/2 行,然后输出最后 1/2 行,并将它们与
paste
组合起来,例如

$ lc=$(wc -l <file.txt); paste <(head -n $((lc/2)) file.txt) <(tail -n $((lc/2)) file.txt)
Today, 12:34    https://123
Today, 21:43    https://456
Today, 12:43    https://789

(上面,

lc
保存行数,然后
head
tail
用于分割文件) 如果您有疑问或者这不是您想要做的,请告诉我。


0
投票

我发现只需使用大括号语法就足以从变量中删除换行符:

foo_stripped=${foo_with_linefeed}

简单有效!

© www.soinside.com 2019 - 2024. All rights reserved.