4

I want to create multiple files at a time using names from a file list.txt, how can I do it?

Sample list.txt:

EOG090W002U
EOG090W00C1
EOG090W00DC
EOG090W00DE
EOG090W00E5
EOG090W00HR
EOG090W00MH
EOG090W00MS
EOG090W00PB
EOG090W00U4
EOG090W00UK
EOG090W00WM
EOG090W00WR

Suppose I have this list.txt containing some id-numbers. Now I want to make separate files using these ids as the name (e.g. EOG090W002U_M0.ctl, EOG090W00C1_M0.ctl, EOG090W00DC_M0.ctl). Also, the contents of the files need to be change accordingly. For example the content of EOG090W002U_M0.ctl, EOG090W00C1_M0.ctl file will be

seqfile = EOG090W002U_p.phy
treefile = Constant.txt
outfile = EOG090W002U_M0_mlc

or

seqfile = EOG090W00C1_p.phy
treefile = Constant.txt
outfile = EOG090W00C1_M0_mlc

where *.phy and Constant.txt will be provided in the same folder.

3
  • Welcome to the site. Please edit your question to explain where you want the newly created files to be placed, if you simply want to create empty files, and whether the filename is to be amended by a suffix etc.
    – AdminBee
    Jan 23, 2020 at 14:48
  • "multiple files at a time"? Please be more clear.
    – FedKad
    Jan 23, 2020 at 14:49
  • 5
    Please don't change your question so much that it becomes a new question. You have now invalidated all answers. You can ask a new question instead.
    – jesse_b
    Jan 23, 2020 at 15:12

5 Answers 5

5

Simplest:

xargs touch <List.txt

The magic is that xargs takes every line in its stdin and adds it as an argument to the command.

1
3

Using GNU parallel in a script:

#!/bin/bash

constant=constant

populate_file () {
    local const=$1
    local file=$(basename -s '.M0.ctl' "$2")
    printf '%s\n%s\n%s\n' \
    "seqfile = ${file}_p.phy" \
    "treefile = ${const}.txt" \
    "outfile = ${file}_M0_mlc" > "$2"
}

export -f populate_file

parallel populate_file "$constant" {}.M0.ctl :::: list.txt

This will read lines from list.txt and execute the populate_file function against each one in parallel. The populate_file function will output the three lines in the desired format into each file.

In the absence of GNU parallel you can use a while read loop:

#!/bin/bash

constant=constant

populate_file () {
    local const=$1
    local file=$(basename -s '.M0.ctl' "$2")
    printf '%s\n%s\n%s\n' \
    "seqfile = ${file}_p.phy" \
    "treefile = ${const}.txt" \
    "outfile = ${file}_M0_mlc" > "$2"
}

while IFS= read -r file; do
    populate_file "$constant" "${file/ /}.M0.ctl"
done < list.txt
7
  • Thanks, but sorry that it shows an error that parallel: command not found. I think I should ask another question. Jan 23, 2020 at 15:47
  • @DebajyotiKabiraj: Install GNU parallel.
    – jesse_b
    Jan 23, 2020 at 15:48
  • Thanks, @Jesse_b the 2nd one working for me, but there is little problem that it is creating space before the extension in the file name as well as inside the filename. seqfile = EOG090W0AK7 _p.phy treefile = SameTREE.txt outfile = EOG090W0AK7 _M0_mlc Jan 24, 2020 at 5:15
  • @DebajyotiKabiraj: Ah, it sounds like your file may have spaces at the end of each line, I'll update a bit later to remove them
    – jesse_b
    Jan 24, 2020 at 12:03
  • @DebajyotiKabiraj: I've updated the second solution to remove the whitespace
    – jesse_b
    Jan 24, 2020 at 14:05
0

You can try something like: for i in $(cat list.txt); do touch $i; done

3
  • 1
    for loop is discouraged to read from file. use while instead.
    – GAD3R
    Jan 23, 2020 at 14:58
  • 1
    Thank you for prompt reply. I am a very beginner in programming , I explaing the entire things. Jan 23, 2020 at 15:00
  • 1
    @DebajyotiKabiraj: You can read about it more on the bash pitfalls wiki
    – jesse_b
    Jan 23, 2020 at 15:05
0

Another way

tr -s '[:blank:]' '[\n*]' < list.txt | 
  while IFS= read -r word; do
   touch "$word";
  done

This answer has been provided with the assumption that all "words" in file was in the same (first) line and where separated by blank characters.

0
#!/bin/bash

tr -d '[:blank:]' < list.txt > outputFile.tmp

for i in $(cat outputFile.tmp)
do
  echo "seqfile = ${i}_p.phy" >> ${i}_M0.ctl
  echo "treefile = constant.txt" >> ${i}_M0.ctl
  echo "outfile = ${i}_M0_mlc" >> ${i}_M0.ctl
done
exit 0

Explanation:

  1. tr -d '[:blank:]' < list.txt > outputFile.tmp will remove blanks from list and copy it to outputFile.tmp
  2. for loop reads all lines from outputFile.tmp and adds the necessary context to the files by creating them on the fly.
4
  • Hello, Thanks The desired results is not coming,... seqfile = EOG090W01HI _M0.ctl_p.phy treefile = constant.txt outfile = EOG090W01HI _M0.ctl_M0_mlc The space is still there and in addition _M0.ctl is included in in the text which is not needed and spaces are still remained Jan 24, 2020 at 7:16
  • I have updated the answer; now please try. Jan 24, 2020 at 9:43
  • Hi Thanks, I tried it gives different kind of outcome.. The file name EOG090W076L?.ctl and inside the file name the results are like... _p.phye = EOG090W076L treefile = SameTree.txt _M0_mlc = EOG090W076L Jan 24, 2020 at 10:28
  • This script was verified and it worked perfectly at my machine. I am using Cygwin terimnal. Try doing dos2unix on your list.txt and then try the script. Don't copy the script using copy paste. Create new script by typing the lines. Jan 25, 2020 at 10:17

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .