1

I have a set of .txt file-pairs. In each pair of files, File1 contains a single integer and File2 contains many lines of text. In the script I'm writing, I'd like to use the integer in File1 to specify how many lines to take off the top of File2 and then write those lines to another file. I'm using gnu-parallel to run this on many file-pairs in parallel.

It seems like a simple way to do this would be to pass the contents of File1 as the parameter for the -n option of head -- is this possible? I've tried using xargs and cat File1, but neither is working.

An example file-pair:

File1:
2                        

File2:
AAA
BBB
CCC
DDD

Desired output:

File3:
AAA
BBB

If I were not using gnu-parallel, I could assign the contents of File1 to a variable (though I don't know if I could pass that into head's -n option?); however, parallel's {} seem to complicate this approach.

I can provide more information if needed.

0

Extending Gilles answer:

parallel 'head -n "$(cat {1})" {2}' ::: File1s* :::+ Corresponding_File2s*

You probably have a lot of File1s that you want linked to File2s. The :::+ does that.

1

Use a command substitution.

head -n "$(cat File1)" File2

A command substitution injects the output of the command into a command line. Newlines at the end of the output are removed, which is exactly what you need here.

Alternatively, in bash (but not in other sh variants), you can use the mapfile builtin to load a file line by line.

mapfile lines <File1
head -n "${lines[0]}" File2

The lines are loaded in an array, so line number n is ${lines[n]}. For the first line, bash also lets you write $line.

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.