3

I'm writing a script which should copy a client system and change some lines in a file.

There is a source file which has a line like:

$DB_HOST = "LegitDbHost";

And the destination file has a line like:

$DB_HOST = "testDbHost";

So i need to replace the destination line with the source line and I want to print out something like this:

Replacing line 12: '$DB_HOST = "testDbHost";' ==with==> '$DB_HOST = "LegitDbHost";'(y/n): 

So far i got this:

toReplace='$DB_HOST';

sourceLine=$(cat ./sourceFile.php | grep -m 1 "$toReplace[[:space:],=]"); destLineNr=$(cat ./destFile.php | grep -n -m 1 "$toReplace[[:space:],=]" | grep -Eo '^[^:]+'); destLine=$(cat ./destFile.php | grep -m 1 "$toReplace[[:space:],=]"); read -p "Replacing line $destLineNr: $destLine ==with==> $sourceLine.(y/n): ";

however, my output looks like this:

==with==> $DB_HOST    ST   = "testDbHost";.(y/n): 

I think it's because the sourceLine has a ; inside and that gets interpreted as a command end. I just don't know how to get around that.

I hope it's understandable.

Edit: as suggested i tried using echo -n

toReplace='$DB_HOST';

sourceLine=$(cat ./sourceFile.php | grep -m 1 "$toReplace[[:space:],=]"); destLineNr=$(cat ./destFile.php | grep -n -m 1 "$toReplace[[:space:],=]" | grep -Eo '^[^:]+'); destLine=$(cat ./destFile.php | grep -m 1 "$toReplace[[:space:],=]");

echo -n "Replacing line $destLineNr: " echo -n $destLine echo -n " ===with===> " echo -n $sourceLine

this prints out:

===with===> $DB_HOST = "testDbHost";OS";
Pascal
  • 31
  • 3
    It sounds more like your problem has to do with your files having Microsoft DOS/Windows CRLF line delimiters. You may want to run dos2unix on them first. – Stéphane Chazelas Feb 20 '21 at 10:11
  • Why not just echo your string with the variable substitutions (optionally with the -n flag to prevent a terminal newline being appended) and then call read -p '(y/n)?' as the next command in the script? That should accomplish what you desire, if I'm understanding it correctly. – Peter J. Mello Feb 20 '21 at 10:59
  • tried echo -n. See my edit. Also tried dos2unix, but it's not installed on the system and I don't have permissions to do so. – Pascal Feb 20 '21 at 12:04
  • To check whether it is as @StéphaneChazelas says use hd or od to just dump a specific line and show output. eg. grep DB_HOST sourceFile.php|hd repeat with destFile.php if you haven't got hd use od -cbx --endian big (btw, your code works for me using bash) – X Tian Feb 20 '21 at 12:31
  • On detecting and removing carriage return characters: https://unix.stackexchange.com/q/79702/315749 and https://unix.stackexchange.com/q/32001/315749 – fra-san Feb 20 '21 at 12:53

1 Answers1

0

Try:

#! /bin/zsh -
die() {
  print -ru2 -- "$@"
  exit 1
}

srcFile=./sourceFile.php dstFile=./destFile.php

toReplace='$DB_HOST'

sourceLine=$(<"$srcFile" grep -Pm1 "\Q$toReplace\E[\s,=]") || die "Can't find $toReplace in $srcFile"

<"$dstFile" grep -nPm 1 "\Q$toReplace\W[\s,=]" | IFS=: read -r destLineNr destLine || die "Can't find $toReplace in $dstFile"

if read -q "?Replacing line $destLineNr: ${(q+)destLine} ==with==> ${(q+)sourceLine}? (y/n): " then ( export destLineNr destLine perl -lpi -e '$_ = $ENV{destLine} if $. == $ENV{destLineNr}' -- "$dstFile" ) fi

Using ${(q+)line} zsh parameter expansion, will make sure CR characters in that variable (as it looks like your input files have MSDOS CRLF delimiters instead of Unix LF ones) is rendered as C-M instead of being sent as-is to the terminal (for a terminal, a CR character makes the cursor go back to the beginning of the line (makes the carriage return for teletypewriter ones)).

  • getting this now: Warning: unknown mime-type for "-ru2" -- using "application/octet-stream" Error: no such file "-ru2" Error: no such file "Can't find $DB_HOST in ./destFile.php" – Pascal Feb 20 '21 at 14:10
  • i have to mention that I'm a total beginner in terms of bash scripting. I got this task from my company, just started to google some commands yesterday. – Pascal Feb 20 '21 at 14:11
  • @Pascal, that's a zsh script not a bash script (note the shebang). Either make it executable with chmod a+x that-script and run it as ./that-script or run it as zsh ./that-script, not bash ./that-script. – Stéphane Chazelas Feb 20 '21 at 15:32
  • tried. it says: -bash: zsh: command not found – Pascal Feb 20 '21 at 15:43