0

I have such a text file:

19-198-0000 NORTHANGER ABBEY
19-198-0001 THIS LITTLE WORK WAS FINISHED IN THE YEAR EIGHTEEN O THREE AND INTENDED FOR IMMEDIATE PUBLICATION IT WAS DISPOSED OF TO A BOOKSELLER IT WAS EVEN ADVERTISED
19-198-0002 NEITHER THE AUTHOR NOR THE PUBLIC HAVE ANY OTHER CONCERN THAN AS SOME OBSERVATION IS NECESSARY UPON THOSE PARTS OF THE WORK WHICH THIRTEEN YEARS HAVE MADE COMPARATIVELY OBSOLETE
19-198-0003 THE PUBLIC ARE ENTREATED TO BEAR IN MIND THAT THIRTEEN YEARS HAVE

and so on. What I want is a way to create the same number of smaller text files as the lines in this initial one, their name to be the digits at the start of the line and their contents to be the rest.

For example, from the small snippet above:

19-198-0000.txt  would contain: NORTHANGER ABBEY
19-198-0001.txt  would contain: THIS LITTLE WORK WAS FINISHED IN THE YEAR EIGHTEEN O THREE AND INTENDED FOR IMMEDIATE PUBLICATION IT WAS DISPOSED OF TO A BOOKSELLER IT WAS EVEN ADVERTISED
19-198-0002.txt  would contain: NEITHER THE AUTHOR NOR THE PUBLIC HAVE ANY OTHER CONCERN THAN AS SOME OBSERVATION IS NECESSARY UPON THOSE PARTS OF THE WORK WHICH THIRTEEN YEARS HAVE MADE COMPARATIVELY OBSOLETE
19-198-0003.txt  would contain: THE PUBLIC ARE ENTREATED TO BEAR IN MIND THAT THIRTEEN YEARS HAVE

and so on.

1
while read -r tag line; do
    printf '%s\n' "$line" >"$tag".txt
done <text.in

When you read two variables with read, the first word is put in the first variable, and the rest of the line is put into the second.

What constitutes a "word" depends on the value of $IFS. By default, read will split the line into words based on spaces, tabs or newlines.

The loop uses this to output the line (minus the first word, or "tag") to a file whose name is taken from the start of the line.

  • oh, didn't see you there :D thanks :) 15 sec interval with nearly the same result, that's cool. – Qubix Jan 31 '17 at 15:58
1

No need for bash at all:

awk '{file = $1".txt"; $1=""; print substr($0,2) > file; close(file)}' a_text_file
  • Get file from the first column, append a .txt to that.
  • Eliminate the first column.
  • Print remaining columns (minus the otherwise leading space) into the file.

Meanwhile, about that while loop in bash:

$ (echo first; echo -n second) | while read line; do echo $line; done
first
$ 

Mmm, silent data loss. Better be sure there are always ultimate newlines, eh?

  • A line without a newline is not a line. Therefore read will not read it. – Kusalananda Jan 31 '17 at 16:05
  • @Kusalananda: actually read does read an unterminated last line, but it returns 'error' (nonzero) status causing the while loop to not process it. OTOH read without -r and echo especially with $line unquoted will alter data containing backslash, whitespace other than single SP, and sometimes glob chars, and sometimes beginning with hyphen. – dave_thompson_085 Jan 31 '17 at 22:40
  • @dave_thompson_085 Thanks for that. To get the second one could do (echo first; echo -n second) | ( while read line; do echo "$line"; done; echo "$line" ) in this specific case at least. – Kusalananda Jan 31 '17 at 22:56
0

managed to do it:

#!/bin/bash

while read -r filename content ; do
    printf '%s\n' "$content" >> "${filename}.txt"
done < some_file.txt

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.