1

I have a file with this content:

# new file text in file 1 # new file text in file 2 # new file text in file 3 

The pattern here is # new file.

I instead of saving each file to xx00, xx01 and xx02, save to specific files: another file, file new, last one.

The 3 files exist in current directory, so I want to provide them as array, overwrite them:

csplit -z infile '/# new file/' "${array[*]}" 

The array can be provided directly

array=('another file' 'file new' 'last one') echo ${array[*]} another file file new last one 

Or list current directory

array=($(find . -type f)) echo ${array[*]} ./another file ./file new ./last one 

A modification of this script could be the solution:

awk -v file="1" -v occur="2" ' { print > (file".txt") } /^\$\$\$\$$/{ count++ if(count%occur==0){ if(file){ close(file".txt") ++file } } } ' Input_file 
0

2 Answers 2

1

I would still consider using csplit, but then rename the generated files afterwards.

#!/bin/sh mkdir ".tmp.$$" || exit 2 csplit -f ".tmp.$$/tmp_" -zk -n 4 "$1" '/# new file/' '{*}' for file in ".tmp.$$"/tmp_* do shift mv -f "$file" "$1" done if ! rmdir ".tmp.$$" 2>/dev/null then echo "Warning: not all file parts were assigned" >&2 rm -rf ".tmp.$$" exit 1 fi exit 0 

Usage

mysplit <source_file> <target_names...> 
0

This works even with spaces and non ascii characters, both inside the text file and the filenames, without using temp files:

infile:

# new file text in file1 blabla # new file text in file2 # new file text in file3 $//*+\ s # new file 4! aaaaaaaaa i^ # new file #¬}}{][|\~@ 

The awk command must be provided with the filenames as individual arguments, using single quotes so does not shell expand (double quotes), in this split.sh script:

awk -v file="0" ' BEGIN { print "AWK arguments:" for (i = 0; i < ARGC; i++){ ARRAY[i] = ARGV[i] print "\047"ARRAY[i]"\047" if (i > 1){ ARGV[i] = "" } } print "Writing:" } !/^# new file$/{ print "writing to: " "\047"ARRAY[file+1]"\047" print $0 >> ARRAY[file+1] } /^# new file$/{ close(file) ++file print "writing to: " "\047"ARRAY[file+1]"\047" print $0 > ARRAY[file+1] } ' 'infile' '1.txt' '2.txt' '3.txt' 'file $_%.txt' '&file _.txt' 

The console looks like this:

AWK arguments: 'awk' 'infile' '1.txt' '2.txt' '3.txt' 'file $_%.txt' '&file _.txt' Writing: writing to: '1.txt' writing to: '1.txt' writing to: '1.txt' writing to: '1.txt' writing to: '2.txt' writing to: '2.txt' writing to: '3.txt' writing to: '3.txt' writing to: '3.txt' writing to: '3.txt' writing to: '3.txt' writing to: '3.txt' writing to: 'file $_%.txt' writing to: 'file $_%.txt' writing to: 'file $_%.txt' writing to: 'file $_%.txt' writing to: '&file _.txt' writing to: '&file _.txt' writing to: '&file _.txt' 

If the arguments are passed as the output from another command (files must exist previously in the filesystem):

' $(ls infile | tr '\n' ' ' ; ls *.txt) 

it splits the arguments by the space:

AWK arguments: 'awk' 'infile' '&file' '_.txt' '1.txt' '2.txt' '3.txt' '_.txt' 'file' '$_%.txt' Writing: writing to: '&file' writing to: '&file' writing to: '&file' writing to: '&file' writing to: '_.txt' writing to: '_.txt' writing to: '1.txt' writing to: '1.txt' writing to: '1.txt' writing to: '1.txt' writing to: '1.txt' writing to: '1.txt' writing to: '2.txt' writing to: '2.txt' writing to: '2.txt' writing to: '2.txt' writing to: '3.txt' writing to: '3.txt' writing to: '3.txt' 

To solve that pass the arguments as an array to awk, separated by a newline and not a space, with this split.sh script:

array=(infile *.txt) awk -v file="0" ' BEGIN { print "AWK arguments:" for (i = 0; i < ARGC; i++){ ARRAY[i] = ARGV[i] print "\047"ARRAY[i]"\047" if (i > 1){ ARGV[i] = "" } } print "Writing:" } !/^# new file$/{ print "writing to: " "\047"ARRAY[file+1]"\047" print $0 >> ARRAY[file+1] } /^# new file$/{ close(file) ++file print "writing to: " "\047"ARRAY[file+1]"\047" print $0 > ARRAY[file+1] } ' "${array[@]}" 

Now the result is:

AWK arguments: 'awk' 'infile' '&file _.txt' '1.txt' '2.txt' '3.txt' 'file $_%.txt' Writing: writing to: '&file _.txt' writing to: '&file _.txt' writing to: '&file _.txt' writing to: '&file _.txt' writing to: '1.txt' writing to: '1.txt' writing to: '2.txt' writing to: '2.txt' writing to: '2.txt' writing to: '2.txt' writing to: '2.txt' writing to: '2.txt' writing to: '3.txt' writing to: '3.txt' writing to: '3.txt' writing to: '3.txt' writing to: 'file $_%.txt' writing to: 'file $_%.txt' writing to: 'file $_%.txt' 

The number of files to write to, must be at least the same as splits which will be performed. If more, the rest will be ignored.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.