user2406786
user2406786

Reputation: 59

Move X amount of lines from one text file to another using bash

I am trying to combine two TXT files somewhat randomly and to do this I am trying to use head and sed to move X amount of lines to a new file and delete the lines from the old file. The problem is, because it is a random value, I can't tell sed just how many lines to delete. Here is what I tried to use that doesn't work as desired:

head -$(shuf -i 3-6 -n1) firstfile.txt > combine.txt && sed -i '1,+$(shuf -i 2-5 -n1)d' firstfile.txt

The problem with the above code is the second use of shuf does not match what the first one is. For example, the first shuf could be 5 and the second shuf could be 3. But I want the second shuf to always be first shuf -1 (so if 1st shuf is 5, second should be 4)

Any solution where I can get the second shuf to match the first or an easier way to do this?

Upvotes: 1

Views: 151

Answers (3)

Léa Gris
Léa Gris

Reputation: 19545

Here is a step-by-step commented method with Bash:

#!/usr/bin/env bash

source='source.txt'
destination='destination.txt'

# Creates test source and destination files, and populates source if needed
if ! [ -f "${source}" ]; then
  # Creates and populates source
  printf 'Source file line %s\n' {1..100} >"${source}"

  # Creates and erases destination
  : > "${destination}"
fi

# Proceeds to test

# Shuffles lines from source file and pipes it to commands group
shuf "${source}" | {

  # Captures 10 shuffled lines
  mapfile -n 10 -t lines

  # If no line read, then exit this sub-shell
  [ 0 -eq "${#lines[@]}" ] && exit

  # Appends those 10 lines to the destination file
  printf '%s\n' "${lines[@]}" >>"${destination}"

  # Writes back the remaining lines to source
  cat >"${source}"
}

Upvotes: 1

M. Nejat Aydin
M. Nejat Aydin

Reputation: 10123

You can do it using a single GNU sed command without resorting to head or a temporary variable:

sed -ni "1,$(shuf -i 3-6 -n1)!{p;d;}; w combine.txt" firstfile.txt

Upvotes: 1

tjm3772
tjm3772

Reputation: 3144

You can save the result of shuf in a variable and reuse it.

shuf_value=$(shuf -i 3-6 -n1)
head -"${shuf_value}" firstfile.txt > combine.txt &&
sed -i "1,+$(( shuf_value-1 ))d" firstfile.txt

Upvotes: 0

Related Questions