Home > Software engineering >  Replacing the last line in Bash
Replacing the last line in Bash

Time:06-16

I have a shell script that's auto generated by a software and it looks something like:

#!/bin/sh

# The directory of this script is the expanded absolute path of the "$qt_prefix/bin" directory.
script_dir_path=`dirname $0`
script_dir_path=`(cd "$script_dir_path"; /bin/pwd)`

/home/akshay/Qt/6.2.4/gcc_64/bin/qmake -qtconf "$script_dir_path/target_qt.conf" $*

I want to replace the last line's first three separators to:

#!/bin/sh

# The directory of this script is the expanded absolute path of the "$qt_prefix/bin" directory.
script_dir_path=`dirname $0`
script_dir_path=`(cd "$script_dir_path"; /bin/pwd)`

/opt/qt/6.2.4/gcc_64/binqmake -qtconf "$script_dir_path/target_qt.conf" $*

I tried getting the last line by doing:

qmake_path=$(tail -n 1 $(find ${QT_ROOT}/android* -maxdepth 0 -type d | sort -r | head -1)/bin/qmake)

Then I used read to split it by space, I don't know how to get the first index, in this case the path. Any help on this is appreciated.

CodePudding user response:

If it is just the short script you show, you can handle the change with sed, e.g.,

sed -i 's/^\/home\/akshay\/Qt/\/opt\/qt/' script.sh

Where -i will edit in-place and the normal substitution of s/find/replace/ is used to locate a line beginning with ^\/home\/akshay\/Qt (e.g. "/home/akshaw/Qt") and replace as \/opt\/qt (e.g. "/opt/qt")

Example Use/Output

Showing the result of the substitution output to stdout you would have:

$ sed 's/^\/home\/akshay\/Qt/\/opt\/qt/' script.sh
#!/bin/sh

# The directory of this script is the expanded absolute path of the "$qt_prefix/bin" directory.
script_dir_path=`dirname $0`
script_dir_path=`(cd "$script_dir_path"; /bin/pwd)`

/opt/qt/6.2.4/gcc_64/bin/qmake -qtconf "$script_dir_path/target_qt.conf" $*

note: you can also use alternate delimiters to avoid having to escape '/', e.g.

sed 's#^/home/akshay/Qt#/opt/qt#' script.sh

That may be easier on the eyes.

Replacing 3-Words Generically

If the text of the first three words in "/one/two/three/..." can change and need to be replaced generically, you can simply use a character list to require one-or-more characters not '/' followed by '/' using [^/] /, you can do:

sed -E -i 's#^/[^/] /[^/] /[^/] /#/opt/qt/#' script.sh

The -E option is also used to specify "extended REGEX" syntax making the ' ' (one-or-more) repetition character available.

With the change, it doesn't matter what the first 3-words are (so long as there is a '/' after the 3rd word, they will be replaced with "/opt/qt/".

CodePudding user response:

Replacing the last line in Bash

I suspect that you're using the wrong tool (tail).

Try head:

head -n -1 <the file>

This will give you <the file> without the last line, which you can then replace with whatever you want in the output to the next step.

If what you want to replace it with is based on the previous last line:

last="$(tail -1 the_file)"

# manipulate $last here 

head -n -1 <the file>
echo "$the_manipulated_last"

CodePudding user response:

Use ed to edit files:

ed -s script.sh <<'EOF'
$s!^/\([^/]*/\)\{3\}!/opt/qt/!
w
EOF

This will replace the first three parts of the path at the start of the last line of the file and save the change.


NetBSD ed and recent versions of GNU ed can use extended regular expressions to make it look a little nicer without the backslashes required by basic regular expressions:

ed -Es script.sh <<'EOF'
$s!^/([^/]*/){3}!/opt/qt/!
w
EOF

CodePudding user response:

Using sed

$ sed '$s~^\([^/]*/\)\{4\}~/opt/qt/~' input_file
#!/bin/sh

# The directory of this script is the expanded absolute path of the "$qt_prefix/bin" directory.
script_dir_path=`dirname $0`
script_dir_path=`(cd "$script_dir_path"; /bin/pwd)`

/opt/qt/6.2.4/gcc_64/bin/qmake -qtconf "$script_dir_path/target_qt.conf" $*
  •  Tags:  
  • bash
  • Related