3

I have to substitute the content of lines from a file with another line (in the same position number 3) in multiple files. The problem looks like the following:

Input1

file.list <- list("a","b","c","d")
file.list <- list("d","e","f","g")
file.list <- list("h","i","l","m")

Input2.file

library(data.table)
library(dplyr)
file.list <- list("z","g","h","s","i")

Input3.file

library(data.table)
library(dplyr)
file.list <- list("s","p","q","r","m")

Input4.file

library(data.table)
library(dplyr)
file.list <- list("x","k","s","e")

Output of Input2.file

library(data.table)
library(dplyr)
file.list <- list("a","b","c","d")

Output of Input3.file

library(data.table)
library(dplyr)
file.list <- list("d","e","f","g")

Output of Input4.file

library(data.table)
library(dplyr)
file.list <- list("h","i","l","m")

I have tried to do as follow:

filename='Input1'
for i in *.file; do #here i loop over the list of files
    while read p $filename; do #here i loop over the lines of Input1 file
        awk '{ if (NR == 3) print "$p"; else print $0}' $i > $i.test; ##here i substitute the line 1 in the files with the line that are in Input1 file
    done;
done

Am doing something wrong because the script is stopping without giving me any message. What am doing wrong? Any Idea?

4
  • It looks like you're redirecting the output of your awk command to a file. Why would you expect to see any messages?
    – igal
    Oct 27, 2017 at 12:55
  • Am outputting into a file because I want to create a new file if this is what you are asking. Or maybe there is something am doing wrong. Oct 27, 2017 at 12:58
  • Yes, that part makes sense to me. But if you output to a file then your output will be in the file - not on the screen. Did you check the files to see if your script worked?
    – igal
    Oct 27, 2017 at 13:01
  • the output file is not produced because the script is stopping but without giving me any error message.. something like this [7]+ Stopped Oct 27, 2017 at 13:02

2 Answers 2

2
$ gawk -i inplace '
    NR == FNR {repl[FNR] = $0; next} 
    FNR == 1  {filenum++} 
    FNR == 3  {$0 = repl[filenum]} 
    {print}
' Input1 Input{2,3,4}.file

$ cat Input2.file
library(data.table)
library(dplyr)
file.list <- list("a","b","c","d")

$ cat Input3.file
library(data.table)
library(dplyr)
file.list <- list("d","e","f","g")

$ cat Input4.file
library(data.table)
library(dplyr)
file.list <- list("h","i","l","m")

Looking at your code:

  1. you're replacing line 3 in each *.file with every line of Input1. You'll be left with the last line of Input1 as line 3 for every *.file.
  2. $p cannot be expanded in your awk script, because it's in single quotes.

Try this:

exec 3<Input1   # set up file descriptor 3 to read from Input1 file
for f in *.file; do
    read -r -u 3 replacement   # read a line from fd 3  
    awk -v rep="$replacement" '{if (NR == 3) print rep; else print $0}' "$f" > "$f.test"
done
exec 3<&-       # close fd 3
2
  • I have used the correction of my script that you have proposed. Could you please explain how it works the "exec" variable that you have created? Thanks in advance. Oct 28, 2017 at 9:00
  • 1
    exec is typically used to replace the current shell process with some other program. For instance exec vim file replaces the shell with an editor and when you exit the editor you don't go back to that shell because it's already gone. When you use exec without a program you can establish redirections in the current shell. Here I open file descriptor 3 to read from the Input 1 file. In a different language you might see fh = open("Input1", "r") Oct 28, 2017 at 13:57
0

to substitute the content of lines from a file with another line

bash + sed solution:

i=0; for f in Input[2-4].file; do ((i++)); sed -n "${i}p" "Input1" > "$f"; done

Viewing results:

$ head Input[2-4].file
==> Input2.file <==
file.list <- list("a","b","c","d")

==> Input3.file <==
file.list <- list("d","e","f","g")

==> Input4.file <==
file.list <- list("h","i","l","m")
2
  • the line in which I Have to substitute the content in the Input2.file,Input3.file , Input4.file is not the first but another number. I put the first here to simplify... Oct 27, 2017 at 13:22
  • 1
    @fusion.slope, you should describe the actual conditions in the question to avoid confusion Oct 27, 2017 at 13:27

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.