1

I want to name each .tar file in the code below and name it based on a list-file that contains the names, but I don't want to mess with the exclusion tag. I have a list file and I was thinking of using a text editor and adding cvf to the beginning of each line I have in a list and then use sed to replace the string cvf, thus adding the flag and then the name follows.

i.e. cvf name1 cvf name2 cvf name3

I tried using sed 's/cvf/word2/g' input.file and as expected it only replaces cvf with the replacement word. I want the replacement word (word2) to change and to be each line from a list file.

Code I want modified: stage ('Zip Repo340') { steps { sh""" tar --exclude='*.tar' -cvf .tar * """ stage ('Zip Repo341') { steps { sh""" tar --exclude='*.tar' -cvf .tar * """ stage ('Zip Repo342') { steps { sh""" tar --exclude='*.tar' -cvf .tar * """

I have 340 of these repositories and I want to name them based on a list file that I have.

List file:

name1 name2 name3

Desired output:

stage ('Zip Repo340') { steps { sh""" tar --exclude='*.tar' -cvf name1.tar * """ stage ('Zip Repo341') { steps { sh""" tar --exclude='*.tar' -cvf name2.tar * """ stage ('Zip Repo342') { steps { sh""" tar --exclude='*.tar' -cvf name3.tar * """

I can add cvf to each line of my list file, but if there's a more elegant solution I'm all ears. The biggest issue I'm having is running the sed replacement command and have the replacement word come from a list file.

Lucid
  • 43
  • 5

2 Answers2

1

You could do something like:

SCRIPT_NAME='outScript.sh'
while read filename; do
  # Replace only the first match:
  sed "0,/-cvf \.tar/s/-cvf \.tar/-cvf ${filename}.tar/" $SCRIPT_NAME > /tmp/tmp.sh
  mv /tmp/tmp.sh $SCRIPT_NAME
done < all_filenames.txt 

Basically, you go through your names file, and for each name, you replace the first non-replaced match

Zorzi
  • 718
  • 4
  • 9
  • Alright, I've got it substituting and naming the files, but it's currently running the command for every occurrence of the pattern, so I end up with 340 lines named the same, another 340 lines named the same as the second variable and I can't get it to only do the first occurence. `while read var; do sed -e "s|cvf|${var}|g1" test2.txt done < shortened.txt ` – Lucid Mar 30 '20 at 17:11
1

This'll do it. Assuming File_1.txt has your code and File_2.txt has the names to replace.

while IFS= read -r line; do
    sed -i "0,/cvf \.tar/{s|cvf \.tar|cvf ${line}\.tar|}" File_1.txt
done < File_2.txt

What is happening here?

  1. sed -i <gobledegook> File_1.txt We are making changes to File_1.txt. What changes? Lets explore the sed script that is the <gobledegook>
  2. "0,/<gobledegook> This says we will be searching for the first occurrence of something
  3. "0,/cvf \.tar/<gobledegook> That something that we will be searching for will be cvf .tar We had to say \.tar because . is a "special character"
  4. "0,/cvf \.tar/{s|<gobledegook>} We are saying here that on the line that our search string exists we want to do another sed script. The new sed script is defined in {} I decided to use | as a delimiter for the second sed script to help distinguish the two.
  5. "0,/cvf \.tar/{s|cvf \.tar|} We are going to replace cvf .tar with something
  6. "0,/cvf \.tar/{s|cvf \.tar|cvf ${line}\.tar|}" We are going to replace cvf .tar with cfv ${line}.tar where ${line} is the current line from File_2.txt

Very similar to this problem

Lenna
  • 1,220
  • 6
  • 22
  • WOW! It just works! You are so amazing and I can't thank you enough. I have been searching for this for quite some time and you are my hero. I will use this A LOT in the future and I even named my script-file Lenna. Thanks for the quick and informative response, hope you're staying safe in the quarantine era. – Lucid Mar 30 '20 at 18:51
  • 1
    Thank you, any chance to spread some ```sed``` love haha. You stay safe too! – Lenna Mar 30 '20 at 19:00