3

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

0

3 Answers 3

6

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'}
Sign up to request clarification or add additional context in comments.

Comments

1

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.

10 Comments

@DavidCRankin The printf command unfortunately doesn't work out, I get the same output like above, but with some space between the left border and the text. But the paste command works! How can the space between the first column and the second column be reduced to 0, 1, ...? And how can I redirect the output of lc to the same text file?
See updated answer. Let me know if you have additional questions.
I still have got the whitespace between time and https. Besides that, I found out that the paste command is better, as the day differs (Today, Yesterday, ..). How would I get rid of whitespace between time and https using the paste command?
You can use paste -d ' ' to use a single space as the delimiter.
Okay and paste -d '' to have no whitespace at all. How can I save the output of the command to the same file?
|
0

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!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.