How to replace a line in bash - bash

How can I replace a line that starts with "string1" with "string2 lala" using Bash script?

use the sed utility
sed -e 's/^string1.*/string2 lala/'
or
sed -e 's/^string1.*/string2 lala/g'
to replace it every time it appears

using bash,
#!/bin/bash
file="myfile"
while read -r line
do
case "$line" in
string1* ) line="string2 lala"
esac
echo "$line"
done <"$file" > temp
mv temp $file
using awk
awk '/^string1/{$0="string2 lala"}1' file

Related

Substitute a variable in a line read from a file

I have read the config file which has the below variable:
export BASE_DIR="\usr\usr1"
In the same script I read a file line by line and I wanted to substitute the ${BASE_DIR} with \usr\usr1.
In the script:
while read line; do
echo $line
done <file.txt
${BASE_DIR}\path1 should be printed as \usr\usr1\path1
Tried eval echo and $(( )).
Can use sed, This command will search and replace a value. The dollar sign is the separator.
sed -ie 's$\${BASE_DIR}$\\usr\\usr1$1' hello.txt
You need to set the variable when you read the line that contains the assignment. Then you can replace it later.
#!/bin/bash
while read line; do
if [[ $line =~ ^BASE_DIR= ]]
then basedir=${line#BASE_DIR=}
fi
line=${line/'${BASE_DIR}'/$basedir}
printf "%s\n" "$line"
done < file.txt > newfile.txt

applying sed to certains line from file using bash

I need you help on this;
I am currently trying to apply a sed command to lines from a file.
2014-08-05T09:29:13+01:00 (INFO:3824.87075728): [27219] [ <email#domain.com>] A message from <user1#domain.com> source <asdfg> this is a test.
I need to apply this sed cmd to this line but keep this others that does not have 'this is a test'
pattern="this\ is\ a test"
while IFS='' read -r line; do
if [[ $line = *"${pattern}"* ]]; then
sed 's/\[ .*\(source\)/\1/g' ${line}
else
echo "${line}"
fi
done < ${INPUT} > ${OUPUT}
I have set the input and output; however ideally keeping the same file would be ideal.
Thank you for your input.
You don't need a loop for this. Use this sed:
sed -i.bak '/this is a test/s/\[ .*\(source\)/\1/g' "${INPUT}"

Transpose one line/lines from column to row using shell

I want convert a column of data in a txt file to a row of a csv file using unix commands.
example:
ApplChk1,
ApplChk2,
v_baseLoanAmountTI,
v_plannedClosingDateField,
downPaymentTI,
this is a column which present in a txt file
I want output as follows in a csv file
ApplChk1,ApplChk2,v_baseLoanAmountTI,v_plannedClosingDateField,downPaymentTI,
Please let me know how to do it.
Thanks in advance
If that's a single column, which you want to convert to row, then there are many possibilities:
tr -d '\n' < filename ; echo # option 1 OR
xargs echo -n < filename ; echo # option 2 (This option however, will shrink spaces & eat quotes) OR
while read x; do echo -n "$x" ; done < filename; echo # option 3
Please let us know, how the input would look like, for multi-line case.
A funny pure bash solution (bash ≥ 4.1):
mapfile -t < file.txt; printf '%s' "${MAPFILE[#]}" $'\n'
Done!
for i in `< file.txt` ; do echo -n $i; done; echo ""
gives the output
ApplChk1,ApplChk2,v_baseLoanAmountTI,v_plannedClosingDateField,downPaymentTI,
To send output to a file:
{ for i in `< file.txt` ; do echo -n $i ; done; echo; } > out.csv
When I run it, this is what happens:
[jenny#jennys:tmp]$ more file.txt
ApplChk1,
ApplChk2,
v_baseLoanAmountTI,
v_plannedClosingDateField,
downPaymentTI,
[jenny#jenny:tmp]$ { for i in `< file.txt` ; do echo -n $i ; done; echo; } > out.csv
[jenny#jenny:tmp]$ more out.csv
ApplChk1,ApplChk2,v_baseLoanAmountTI,v_plannedClosingDateField,downPaymentTI,
perl -pe 's/\n//g' your_file
the above will output to stdout.
if you want to do it in place:
perl -pi -e 's/\n//g' your_file
You could use the Linux command sed to replace line \n breaks by commas , or space :
sed -z 's/\n/,/g' test.txt > test.csv
You could also add the -i option if you want to change file in-place :
sed -i -z 's/\n/,/g' test.txt

Skip line in text file which starts with '#' via KornShell (ksh)

I am trying to write a script which reads a text file and saves each line to a string. I would also like the script to skip any lines which start with a hash symbol. Any suggestions?
You should not leave skipping lines to ksh. E.g. do this:
grep -v '^#' INPUTFILE | while IFS="" read line ; do echo $line ; done
And instead of the echo part do whatever you want.
Or if ksh does not support this syntax:
grep -v '^#' INPUTFILE > tmpfile
while IFS="" read line ; do echo $line ; done < tmpfile
rm tmpfile
while read -r line; do
[[ "$line" = *( )#* ]] && continue
# do something with "$line"
done < filename
look for "File Name Patterns" or "File Name Generation" in the ksh man page.

How can I tokenize $PATH by using awk?

How can I tokenize $PATH by using awk?
I tried 3 hours, but it totally screwed out.
#!/bin/bash
i=1
while true; do
token=$($echo $PATH | awk -F ':' '{print $"$i"}')
if [ -z "$token" ]; then
break
fi
((i++))
if [ -a "$TOKEN/$1" ]; then
echo "$TOKEN/$1"
break
fi
break
done
When I run this code, I got
/home/$USERID/bin/ff: line 6: /home/$USERID/bin:/usr/local/symlinks:/usr/local/scripts:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/home/$USERID/bin: No such file or directory
How can I change my program?
What are you trying to do?
This will let you iterate against the individual paths:
echo $PATH | tr ':' '\n' | while read line; do echo $line; done
As #SiegeX notes, an even shorter version works
echo $PATH | while read -d ':' line; do echo $line; done
Do the whole thing in awk
#!/bin/bash
awk -v addPath="$1" 'BEGIN{RS=":";ORS=addPath "\n"}{$1=$1}1' <<< $PATH
Proof of Concept
$ addPath="/foo"
$ awk -v addPath="$addPath" 'BEGIN{RS=":";ORS=addPath "\n"}{$1=$1}1' <<< $PATH
/usr/local/bin/foo
/usr/bin/foo
/bin/foo
/usr/games/foo
/usr/lib/java/bin/foo
/usr/lib/qt/bin/foo
/usr/share/texmf/bin/foo
./foo
/sbin/foo
/usr/sbin/foo
/usr/local/sbin/foo
I think simple tr : \\n would suffice. Pipe it with sed 's#$#blabla#g' to add something to the lines and that's it.
You don't need to use external tools such as awk or tr to tokenize the PATH. Bash is capable of doing so:
#!/bin/sh
IFS=:
for p in $PATH
do
if [ -a "$p/$1" ]; then
echo "$p/$1"
break
fi
done
The IFS is a bash built-in variable which bash use as an input field separator (IFS).

Resources