sed not obeying \t or actual tab - linux

I have seen this question a lot and I have tried everything I found and still I cannot get this working.
I am trying to add a new line in my virtualhost file for a script that manages aliases and have the new entry tabbed properly.
I have this line that adds the alias after I check it doesn't exist.
My final attempt: (still no tab.. I actually have 2 tabs in this one)
sed -i "/ServerAlias www.$account/a $newAlias" "$VHOST_FILE"
Here's it again with a single tab
sed -i "/ServerAlias www.$account/a $newAlias" "$VHOST_FILE"
I have also tried: (these all prefix with t instead of using a tab)
sed -i "/ServerAlias www.$account/a \t$newAlias" "$VHOST_FILE"
sed -i "/ServerAlias www.$account/a \\t$newAlias" "$VHOST_FILE"
sed -i "/ServerAlias www.$account/a\t$newAlias" "$VHOST_FILE"
sed -i "/ServerAlias www.$account/a\\t$newAlias" "$VHOST_FILE"
What am I missing here?
Thanks for any assistance

You're close. The problem is that \\ becomes a literal \ in double quotes, so \\t and \t become the same thing.
Escape them to get the result you want:
sed -i "/ServerAlias www.$account/a \\\\t$newAlias" "$VHOST_FILE"

In bash, you can use $'\t' to insert tab.
sed "/ServerAlias www.$account/a"$'\t'"$newAlias" "$VHOST_FILE"

There are many ways to accomplish the same thing. The best approach is to use stuff you can easily understand:
line=$'\t'"$newAlias" # a tab followed by contents of newAlias
sed "/ServerAlias www.$account/a $line" "$VHOST_FILE"
and then combine these (next time) once you've got a good grasp on what is going on.

Related

How to remove `^I` character in Linux?

This looks a number of space(20170628 ,) but using cat -A it shows ^I (20170628^I,).
I tried sed -i '/s/^I//g' xxx and sed -i '/s/\^I//g' xxx, but neither works.
How to delete this character ? Any help is appreciated.
That's a tab character, so you can use:
sed -i 's/\t//g/' fileToChange
for this.

Trying to use grep to find something, then output a different part of the line

Say for instance I'm searching a line that is like this:
Color asdf
and I use grep to find that line, like grep asdf file.txt
How would I then display Color? Learning linux is hard.
With the command line tool sed you can replace stings by using regular expressions:
echo "Color asdf" | sed 's/\([^ ]*\).*/\1/'
This part: \([^ ]*\).* is a regular expresion. The first part of the regex: [^ ]*, matches any character except a space as many times as possible and what's between the \( and \) is being captured in the variable \1. Then you also match the remaining part of the string with .* and replace all of that with only the first word which was captured by \([^ ]*\) by using \1 in the replace part of the sed command.
Here some more info about sed:
http://linux.about.com/od/commands/a/Example-Uses-Of-Sed-Cmdsedxa.htm
You could use sed:
sed -n 's/[[:space:]][[:space:]]*asdf$//p' file.txt
Details:
The -n option tells sed not to print the pattern space automatically. Basically, it doesn't output anything unless you tell it to.
The s command of sed replaces text. Here, if a line ends with asdf, preceded by at least one whitespace character, we replace all of that with nothing and then print the line (notice the p flag at the end of the s command). The printing is only done if something was actually replaced. More information about the s command can be found e. g. in the GNU sed manual.
Edit for clarity: When using single quotes, parameter expansion does not work and thus, variables won't be replaced. To use variables, use double quotes:
search=asdf
sed -n "s/[[:space:]][[:space:]]*${search}\$//p" file.txt
If you'd really like to use grep here, you could pipe the output from grep into cut:
grep -h asdf *.txt | cut -s -d -f 1
Note that there have to be two spaces after the -d option to cut - the first tells cut to use a blank as the field delimiter (I'm assuming your fields are blank-delimited rather than tab-delimited), while the second separates the -d option from the following option (-f).
But, yeah, sed or awk are probably your friends here... :-)
you can color pattern in the line using grep
grep --colour -o 'asdf' file.txt
edit: the -o option will print only the patterns

linux shell sed command

I have file sedFile.txt which has string in format CONNECTION='mysql://user:user#10.79.19.2:3308/SSMS/SUBSCRIBE';
I created one script which has following lines:
fin=CONNECTION='mysql://user:user#10.79.19.2:3308/SSMS/SUBSCRIBE';
repla=connection
sed -i "s/\$fin/$repla/g" /home/sedFile.txt
Even though the script is running, it's not doing changes in my file.
I tried following:
sed -i 's/${fin}/${repla}/g' /home/sedFile.txt
sed -i 's/^$fin/$repla/g' /home/sedFile.txt
sed -i "s/$fin/$repla/g" /home/sedFile.txt
sed -i "s/${fin}/${repla}/g" /home/sedFile.txt
If you want the single quotes to be included in the pattern you have to quote or escape them:
fin="CONNECTION='mysql://user:user#10.79.19.2:3308/SSMS/SUBSCRIBE'"
then, use any of the four lines you tried (i.e. not the one with \$fin).
Update: In order to make sed work, you cannot use / to separate the pattern and the substitution, because this character exists in the string already. Use a different separator:
sed -i "s,$fin,$repla,g" /home/sedFile.txt
Might be the same as the other answers, but I doesn't hurt to try
fin="CONNECTION='mysql://user:user#10.79.19.2:3308/SSMS/SUBSCRIBE';"
repla="connection"
sed -i "s|${fin}|${repla}|g" /home/sedFile.txt
fin="CONNECTION='mysql://user:user#10.79.19.2:3308/SSMS/SUBSCRIBE'"
repla=connection
in=$fin out=$repla perl -pi.nk -e 's/\Q$ENV{"in"}/$ENV{"out"}/g' /home/sedFile.txt

How to remove a special character in a string in a file using linux commands

I need to remove the character : from a file. Ex: I have numbers in the following format:
b3:07:4d
I want them to be like:
b3074d
I am using the following command:
grep ':' source.txt | sed -e 's/://' > des.txt
I am new to Linux. The file is quite big & I want to make sure I'm using the write command.
You can do without the grep:
sed -e 's/://g' source.txt > des.txt
The -i option edits the file in place.
sed -i 's/://' source.txt
the first part isn't right as it'll completely omit lines which don't contain :
below is untested but should be right. The g at end of the regex is for global, means it should get them all.
sed -e 's/://g' source.txt > out.txt
updated to better syntax from Jon Lin's answer but you still want the /g I would think

Use sed to delete all leading/following blank spaces in a text file

File1:
hello
world
How would one delete the leading/trailing blank spaces within this file using sed - using one command (no intermediate files)?
I've currently got:
sed -e 's/^[ \t]*//' a > b
For leading spaces.
sed 's/ *$//' b > c
And this for trailing spaces.
You almost got it:
sed -e 's/^[ \t]*//;s/[ \t]*$//' a > c
Moreover on some flavours of sed, there is also an option for editing inline:
sed -i -e 's/^[ \t]*//;s/[ \t]*$//' a
easier way, using awk
awk '{$1=$1}1' file
or
awk '{gsub(/^ +| +$/,"")}1' file
perl -lape 's/^\s+|\s+$//g'
Honestly, I know perl regexps the best, so I find perl -lape much easier to use than sed -e.
Also, to answer the original question, you can have sed execute multiple operations like this:
sed -e 's/something/something else/' -e 's/another substitution/another replacement/'
Apparently you can also put the two substitutions in one string and separate them with a semicolon, as indicated in another answer.
Note that in the more general case of applying several filters in a row to an input file without using intermediate files, the solution is to use pipes:
sed -e 's/^[ \t]*//' a | sed -e 's/ *$//' > c
Obviously they are not required here because one invocation of sed is sufficient, but if the second sed command was something different, like uniq or sort, then this pattern is the right one.

Resources