about unix command "sed" - unix

I want to do the following substitution in a text file:
the original string: "---a---"
after substitution : "---\a---"
and I run the following command:
sed -r -e "s/-(a)-/-\\\1-/g" test.txt
but it doesn't give the right result. What command args should I use?

Remember that backslashes are significant in Bash's double-quoted strings as well as in sed itself. Either use single quotes:
sed -r -e 's/-(a)-/-\\\1-/g' test.txt
Or escape the backslashes again:
sed -r -e "s/-(a)-/-\\\\\\1-/g" test.txt
If you echo the strings, you'll see what's happening:
$ echo "s/-(a)-/-\\\1-/g"
s/-(a)-/-\\1-/g
$ echo 's/-(a)-/-\\\1-/g'
s/-(a)-/-\\\1-/g
$ echo "s/-(a)-/-\\\\\\1-/g"
s/-(a)-/-\\\1-/g
The first one (your original) just looks like a literal backslash followed by a literal 1 to sed.

Try sed -r -e "s/-(a)-/-\\\\\\1-/g" or sed -r -e 's/-(a)-/-\\\1-/g'
The problem is that \ is captured by bash if you use double quotes.

With " you will have to do something like:
[jaypal:~/Temp] echo "---a---" | sed -r "s/-(a)-/-\\\\\1-/g"
---\a---

You have to replace 1 with a
sed -r -e "s/-(a)-/-\\\a-/g" test.txt

so many answers ......
Kaizen ~/so_test
$ echo "---a---" | sed -n 's/a/\\a/p'
---\a---
since you have a text file the following should work :
sed -i 's/a/\\a/g' filename.txt ;
does this help ?

Related

How can I put a sed command into a while loop?

Hoping someone kind can help me pls!
I have an file input.list:
/scratch/user/IFS/IFS001/IFS003.GATK.recal.bam
/scratch/user/IFS/IFS002/IFS002.GATK.recal.bam
/scratch/user/EGS/ZFXHG22/ZFXHG22.GATK.recal.bam
and I want to extract the bit before .GATK.recal.bam - I have found a solution for this:
sed 's/\.GATK\.recal\.bam.*//' input.list | sed 's#.*/##'
I now want to incorporate this into a while loop but it's not working... please can someone take a look and guide me where I'm doing wrong. My attempt is below:
while read -r line; do ID=${sed 's/\.GATK\.recal\.bam.*//' $line | sed 's#.*/##'}; sbatch script.sh $ID; done < input.list
Apologies for the easy Q...
You can use the output of the sed command as input for the loop:
sed 'COMMAND' input.file | while read -r id ; do
some_command "${id}"
done
Instead of the loop, also xargs could be used:
sed 'COMMAND' input.file | xargs -n1 some_command
ps: GNU sed supports to execute the result of a s operation as a command. I wouldn't recommend to use this in production, for portability reasons at least, but it's worth mention probably:
sed 's/\(.*\)\.GATK\.recal\.bam.*/sbatch script.sh \1/e' input.file
You can do this in straight up bash (If you're using that shell; ksh93 and zsh will be very similar) no sed required:
while read -r line; do
id="${line##*/}" # Remove everything up to the last / in the string
id="${id%.GATK.recal.bam}" # Remove the trailing suffix
sbatch script.sh "$id"
done < input.list
At the very least you can use a single sed call per line:
id=$(sed -e 's/\.GATK\.recal\.bam$//' -e 's#.*/##' <<<"$line")
or with plain sh
id=$(printf "%s\n" "$line" | sed -e 's/\.GATK\.recal\.bam$//' -e 's#.*/##')

Replace Text using variables in Sed not working

I need to modify an xml file using Sed to replace the line
url="jdbc:oracle:thin:#//ttpdbscan.axel.net:1521/axel.telco.net"
with
url="jdbc:oracle:thin:#//ttpdbscan.axeltelecom.net:1598/axelPRD.telco.net"
I have stored the lines like this
ACTUAL_DB=$(sed -n 's#^.*url="\(.*\).*"#\1#p' $FILE.xml)
and
NEW_DB="jdbc:oracle:thin:#//ttpdbscan.axeltelecom.net:1598/axelPRD.telco.net"
And the replacing method is this one
sed -i "s#$ACTUAL_DB#$NEW_DB#g" $File.xml
The problem is that when I run the script the file stays the same.
I have echoed the variables and all of them return the correct values.
Assuming the file you have is File.xml (if it is not a variable), you may use
sed -i "s#${ACTUAL_DB}#${NEW_DB}#g" File.xml
Try also with other delimiters:
sed -i "s~${ACTUAL_DB}~${NEW_DB}~g" File.xml
If your sed does not support -i use
sed "s~${ACTUAL_DB}~${NEW_DB}~g" File.xml 1<> File.xml
See sed edit file in place
So I saved the output into another file and found out that the string had an extra space
so it looked like this
ACTUAL_DB= "jdbc:oracle:thin:#//ttpdbscan.axel.net:1521/axel.telco.net "
I removed the extra space with
"$(echo -e "${ACTUAL_DB}" | tr -d '[:space:]')"
And now the sed is working as intended

Extract filename

So I am new to SED and Unix and I would like to replace the following file:
1500:../someFile.C:111 error
1869:../anotherFile.C:222 error
1869:../anotherFile2.Cxx:333 error
//thousands of more lines with same structure
With the followig file
someFile.c
anotherFile.c
anotherFile2.Cxx
Basically, I just want to extract the filename from every line.
So far, I have read the documentation on sed and the second answer here. My best attempt was to use a regex as follows:
sed "s/.\*\/.:.*//g" myFile.txt
Lots of ways to do this.
Sure, you could use sed:
sed 's/^[^:]*://;s/:.*//;s#\.\./##' input.txt
sed 's%.*:\.\./\([^:]*\):.*%\1%' input.txt
Or you could use a series of grep -o instances in a pipe:
grep -o ':[^:]*:' input.txt | grep -o '[^:]\{1,\}' | grep -o '/.*' | grep -o '[^/]\{1,\}'
You could even use awk:
awk -F: '{sub(/\.\.\//,"",$2); print $2}' input.txt
But the simplest way would probably be to use cut:
cut -d: -f2 input.txt | cut -d/ -f2
You can capture the substring between last / and following : and replace the whole string with the captured string(\1).
sed 's#.*/\([^:]\+\).*#\1#g' myFile.txt
someFile.C
anotherFile.C
anotherFile2.Cxx
OR , with little less escaping, sed with -r flag.
sed -r 's#.*/([^:]+).*#\1#g' myFile.txt
Or if you want to use grep,this will only work if your grep supports -P flag which will enable PCRE:
grep -oP '.*/\K[^:]+' myFile.txt
someFile.C
anotherFile.C
anotherFile2.Cxx

Unable to remove control # from file

I have a file which has ^# in it and I am unable to remove it using sed or replace command in python. I can see ^# only when I open the file in vi editor. Please suggest. Below is what i tried using sed.
sed 's/^#/?/g' filename
Tested on Linux, not sure if syntax varies elsewhere, try
$ printf 'abc\0baz\n' | cat -v
abc^#baz
$ printf 'abc\0baz\n' | tr -d '\0' | cat -v
abcbaz
tr will delete all ASCII NUL characters from input.. cat -v is used here to highlight non-printing characters
for file input, use tr -d '\0' <filename
GNU sed (and possibly few other implementations) allow to use hex value to represent a character
$ printf 'abc\0baz\n' | sed 's/\x00//g' | cat -v
abcbaz
so, for in-place editing, use sed -i 's/\x00//g' filename (See also: sed in-place flag that works both on Mac (BSD) and Linux )

Print specific lines using sed

Im trying to print only lines that do not start with a letter from the file "main"
Ive tried sed -n '/^[a-z]/ /!w' main
and it gives me "w': event not found"
With sed as requested:
sed '/^[[:alpha:]]/d' main
or
sed -n '/^[^[:alpha:]]/p' main
or
sed -n '/^[[:alpha:]]/!p' main
Note: you could use [a-z] inplace of [[:alpha:]] but I prefer the latter because it is safe to use across different locales
there are many other ways to print lines
sed -n '/^[^a-zA-Z]/p' main
sed -n '/^[^a-z]/Ip' main
awk 'BEGIN{IGNORECASE=1}!/^[a-z]/' main
grep -vi "^[a-z]" main
ruby -ne 'print unless /^[a-z]/i' main
shell
while read -r line
do
case "$line" in
[^a-zA-Z]*) echo $line;;
esac
done < main
grep -v '^[a-z]' main
will do it.

Resources