Exclude smililar string while using sed - linux

I have a some scripts into a directory and this directory containing other folders also. Which ever script are residing in my first (parent) directory I want to replace all 'dev' string into prod. but in some of the script I am nullifying the out by using dev/null . I don't want to change this as prod/null.
I am replacing all other 'dev' using below command.
grep -rl dev somedir|xargs sed -i 's/dev/prod/g'
Please let me know if there is any way to exclude changing dev/null to prod/null
Thanks.

If each entry in grep -r1 dev somedir is separated by a newline, you can use this
grep -rl dev somedir | grep -v "dev/null" | xargs sed -i 's/dev/prod/g'

It is possible to replace /dev/null to some other string (i.e. /xxx/null) before doing dev -> prog substitution and change it to /dev/null later.
grep -rl dev somedir|xargs sed -i -e 's!/dev/null!/xxx/null!g' -e 's/dev/prod/g' -e 's!/xxx/null!/dev/null!g'

Related

Filter directories in piped input

I have a bash command that lists a number of files and directories. I want to remove everything that is not an existing directory. Is there anyway I can do this without creating a script of my own? I.e. I want to use pre-existing programs available in linux.
E.g. Given that I have this folder:
dir1/
dir2/
file.txt
I want to be able to run something like:
echo dir1 dir2 file.txt somethingThatDoesNotExist | xargs [ theCommandIAmLookingFor]
and get
dir1
dir2
It would be better if the command generating the putative paths used a better delimeter, but you might be looking for something like:
... | xargs -n 1 sh -c 'test -d "$0" && echo $0'
You can use this command line using grep -v:
your_command | grep -vxFf <(printf '%s\n' */ | sed 's/.$//') -
This will filter out all the sub-directories in current path from your list.
If in case you want to list only existing directories then remove -v as:
your_command | grep -xFf <(printf '%s\n' */ | sed 's/.$//') -
Note that glob */ prints all sub-directories in current path with a trailing / and sed is used to remove this last /.

How to find all files containing specific text (which includes a backslash)?

I thought I found the perfect answer with How do I find all files containing specific text on Linux?, so I tried it:
[Michael#devserver ~]$ grep -rnw '/var/www/concrete5.7.5.9/' -e "Concrete\Core\Block\BlockController"
[Michael#devserver ~]$
None show, but I know there should have been a match.
[Michael#devserver ~]$ grep -rnw '/var/www/concrete5.7.5.9/concrete/blocks/html' -e "BlockController"
/var/www/concrete5.7.5.9/concrete/blocks/html/controller.php:5:use \Concrete\Core\Block\BlockController;
/var/www/concrete5.7.5.9/concrete/blocks/html/controller.php:7:class Controller extends BlockController
[Michael#devserver ~]$
I also tried escaping the backslash to no avail.
[Michael#devserver ~]$ grep -rnw '/var/www/concrete5.7.5.9/' -e "Concrete\\Core\\Block\\BlockController"
[Michael#devserver ~]$
Also tried single quotes to no avail.
[Michael#devserver ~]$ grep -rnw '/var/www/concrete5.7.5.9/' -e 'Concrete\Core\Block\BlockController'
[Michael#devserver ~]$
How to find all files containing specific text which includes a backslash on Linux?
Use single quotes and escape backslash.
grep -rnw '/var/www/concrete5.7.5.9/' -e'Concrete\\Core\\Block\\BlockController'
Use single quotes.
grep -rnw '/var/www/concrete5.7.5.9/' -e 'Concrete\Core\Block\BlockController'
Grep has an option -F to interpret the pattern literally and not as a regular expression. For example:
$ cat infile
use \Concrete\Core\Block\BlockController;
class Controller extends BlockController
$ grep 'Concrete\Core\Block\BlockController' infile # No match!
$ grep -F 'Concrete\Core\Block\BlockController' infile # Matches!
use \Concrete\Core\Block\BlockController;

Search and Replace SED Linux

I need to convert my all url relative path
https://www.example.com/image/abc.gif to /image/abc.gif
i tried this command but not worked for https:\\ section . How can i use https\\ in this command .
grep -rl "http://www.example.com" /root/ | xargs sed -i 's/http://www.example.com//g'
The following will do the job:
echo "https://www.example.com/image/abc.gif" | sed 's/https:\/\/www\.example\.com//g'
OUTPUT
/image/abc.gif
You can use regular expressions, the -r indicates extended regexes. The ? says 0 or 1 occurrence of 's'.
echo "http://www.example.com/image/abc.gif" | sed -r 's/https?:\/\/www\.example\.com//g'

How to change a windows path to a linux path in all files under a directory using sed

I copied a directory structure from a windows box to a Linux box and I would like to use sed to replace c:\IBM\WebSphere with /opt/IBM/WebSphere in all files under this directory.
Any thoughts?
I think sed is a little inconvenient for that purpose, if you want to change the actual files you can use perl one-liner
perl -pi -e 's/c:\\IBM\\/\/opt\/IBM\//g' *
Add or adjust the paths according to what you need (add WebSphere if you want the replacement to change only these dirs)
Since sed can take any character as a delimiter, use
sed -e 's_\\_/_g'
to replace the \ to /.
sed -e 's_[Cc]:_/opt_g'
to replace the c: with /opt
You can string those together:
echo "C:\\IBM\\WebSphere" | sed -e 's_\\_/_g' -e 's_[Cc]:_/opt_g'
Output:
/opt/IBM/WebSphere
I don't see an awk solution, just add one:
awk -F'\' -v OFS='/' '$1=/^c:/?"/opt":$1'
test:
kent$ awk -F'\' -v OFS='/' '$1=/^c:/?"/opt":$1' <<<'c:\IBM\WebSphere'
/opt/IBM/WebSphere
echo "C:\Users\San.Tan\My Folder\project1" | sed -e 's/C:\\/mnt\/c\//;s/\\/\//g'
replaces
C:\Users\San.Tan\My Folder\project1
to
mnt/c/Users/San.Tan/My Folder/project1
in case someone needs to replace windows paths to Windows Subsystem for Linux(WSL) paths

grep command working in testdir but not in "real" directory

I just thought I had found my solution because the command works in my test directory.
grep -H -e 'author="[^"].*' *.xml | cut -d: -f1 | xargs -I '{}' mv {} mydir/.
But using the command in the non-test-direcory the command did not work:
This is the error message:
grep: unknown option -- O
Usage: grep [OPTION]... PATTERN [FILE]...
Try `grep --help' for more information.
Not even this worked:
$ grep -H author *.xml
or this:
$ grep -H 'author' *.xml
(same error message)
I suspect it has some relation to the file names or the amount of files.
I have almost 3000 files in the non-test-directory and only 20 in my test directory.
In both directories almost all file names contain spaces and " - ".
Some more info:
I'm using Cygwin.
I am not allowed to change the filenames
Try this (updated):
grep -HlZ 'author="[^"].*' -- *.xml | xargs -0 -I {} mv -- {} mydir/
EXPLANATION (updated)
In your "real" directory you have a file with name starting with -O.
Your shell expands the file list *.xml and grep takes your - starting filename as an option (not valid). Same thing happens with mv. As explained in the Common options section of info coreutils, you can use -- to delimit the option list. What comes after -- is considered as an operand, not an option.
Using the -l (lowercase L) option, grep outputs only the filename of matching files, so you don't need to use cut.
To correctly handle every strange filename, you have to use the pair -Z in grep and -0 in xargs.
No need to use -e because your pattern does not begin with -.
Hope this will help!

Resources