Reputation: 301
I've got a text file
Today, 12:34
Today, 21:43
Today, 12:43
https://123
https://456
https://789
and wanted to print each line into an array. Therefore I used:
readarray array <'file.txt'
Now I'd like to create a new array mixing date and the corresponding link, so in this case, line 1 corresponds with line 4 and so on. I wrote
declare -a array2
array2[0]=${array[0]}${array[3]}
array2[1]=${array[1]}${array[4]}
...
printing the whole array2 using "echo ${array2[*]}" gets the following:
Today, 12:34
https://123
Today, 21:43
https://456
Today, 12:43
https://789
Why are there newlines between the elements, so e.g. between array2[0] and array2[1] ? How could I get rid of them? And why is there an empty space before T in the second and the following lines? And is there a possibility to write the code above in a loop?
Kind regards, X3nion
Upvotes: 2
Views: 1012
Reputation: 1
I found that simply using brace bracket syntax suffices to remove the line feed from a variable thusly:
foo_stripped=${foo_with_linefeed}
Simple and effective!
Upvotes: 0
Reputation: 84521
An awk
solution would be much simpler (and much faster). Simply read all lines containing "Today"
into an array in awk
. Then beginning with the line not containing "Today"
write the current line followed by the associated line from the array, e.g.
awk '/Today/{a[++n] = $0; next} {printf "%s\t%s\n", $0, a[++m]}' file.txt
Example Use/Output
With your example lines in file.txt
, you would receive:
$ 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
Or if you wanted to change the order:
$ 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
Addition Per-Comment
If you are receiving whitespace before the output with awk
that is due to having whitespace before the first field. To eliminate the whitespace, you can force awk
to recalculate each field, removing whitespace simply by setting a field equal to itself, e.g.
awk '{$1 = $1} /Today/{a[++n] = $0; next} {printf "%s\t%s\n", a[++m], $0}' file.txt
By setting the first field equal to itself ($1 = $1
), you force awk
to recalculate each field which would eliminate leading whitespace. Take for example your data with leading whitespace (each line is preceded by 3-spaces):
Today, 12:34
Today, 21:43
Today, 12:43
https://123
https://456
https://789
Using the updated command gives the answers shown above with the whitespace removed.
Using paste
You can use the paste
command as another option along with the wc -l
(word count lines) command. Simply determined the number of lines and then use process substitution to output the first 1/2 of the lines followed by the last 1/2 of the lines and combine them with paste
, e.g.
$ 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
(above, lc
holds the line-count and then head
and tail
are used to split the file)
Let me know if you have questions or if this isn't what you were attempting to do.
Upvotes: 1
Reputation: 295291
Use the -t
argument to prevent the newlines from being included in the data stored in the individual array elements:
readarray -t array <file.txt
BTW, you can always strip your newlines after-the-fact, even if you don't prevent them from being read in the first place, by using the ${var%suffix}
parameter expansion with the $'\n'
syntax to refer to a newline literal:
array2[0]=${array[0]%$'\n'}${array[3]%$'\n'}
Upvotes: 5