0

I've got a text file given, and the results and the counts vary (date, link and id can be anything). However, the count of dates, links and id's is always the same (so n - n - n for any positive integer n). Is n a positive integer, then the lines n, (n + k/3) and (n+2(k/3)), where k is the number of all lines, belong together.

As en example, I picked out n=3. So lines (1 | 4 | 7), (2 | 5 | 8) and (3 | 6 | 9) belong together:

Today, 17:09
Yesterday, 09:44
08.09.2020
07.09.2020
06.09.2020
/s-show/Link111...
/s-show/Link211...
/s-show/Link311...
/s-show/Link411...
/s-show/Link511...
id="1222222222"
id="2222222222"
id="3222222222"
id="4222222222"
id="5222222222"

I would like to sort the text file as the following:

id="1222222222"Today, 17:09/s-show/Link111...
id="2222222222"Yesterday, 09:44/s-show/Link211
id="3222222222"08.09.2020/s-show/Link311
id="4222222222"07.09.2020/s-show/Link411
id="5222222222"06.09.2020/s-show/Link511

In a former question, I only had two categories (date and link) and was adviced to do it like the following:

lc=$(wc -l <Textfile); paste -d '' <(head -n $((lc/2)) Textfile) <(tail -n  
$((lc/2)) Textfile)

However, here I have 3 categories and the head and tail command won't let me read only the lines in the middle. How could this be solved?

16
  • You can combine head and tail to get content in the middle. (It's not what I would actually choose to do, but it's certainly something you can do). Commented Sep 8, 2020 at 22:58
  • 1
    ...in terms of what I'd actually do, I wouldn't choose to use bash for the job at hand at all. A programming language with access to seek() and tell() calls will allow a much more efficient implementation. Commented Sep 8, 2020 at 23:00
  • 1
    ...as for your immediate question, though -- do you consider How can I extract a predetermined range of lines from a text file on UNIX a duplicate? As I understand it, it's narrowly addressing the part of your problem you don't currently know how to do. Commented Sep 8, 2020 at 23:03
  • 1
    paste file1 file2 file3. Which is to say, if you have three separate files, the whole problem becomes completely trivial. Commented Sep 9, 2020 at 0:00
  • 1
    ...if you really don't want tabs added, add the -d argument to paste, as in, paste -d '' file1 file2 file3. Commented Sep 9, 2020 at 0:03

1 Answer 1

0

Leveraging the techniques taught in How can I extract a predetermined range of lines from a text file on Unix? --

#!/usr/bin/env bash

input=$1
total_lines=$(wc -l <"$1")
sections=$2

lines_per_section=$(( total_lines / sections ))
if (( lines_per_section * sections != total_lines )); then
  echo "ERROR: ${total_lines} does not evenly divide into ${sections} sections" >&2
  exit 1
fi

start=0
ranges=( )
for (( i=0; i<sections; i++ )); do
  ranges+=( "$start:$(( start + lines_per_section ))" )
  (( start += lines_per_section ))
done

get_range() { sed -n "$(( $1 + 1 )),$(( $2 ))p;$(( $2 + 1 ))q" <"$input"; }
consolidate_input() {
  if (( $# )); then
    current=$1; shift
    paste <(get_range "${current%:*}" "${current#*:}") <(consolidate_input "$@")
  fi
}

consolidate_input "${ranges[@]}"

But don't do that. Just put your three sections in three separate files, so you can use paste file1 file2 file3.

Sign up to request clarification or add additional context in comments.

1 Comment

Okay the paste file1 file 2 file3 command with -d ' ' will do nicely.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.