How to add a line in files recursively bash? - bash

I use the command to add one line at the beginning of the php files in the current directory and its subdirrectories recursively.
find . -name "*.php" -exec sed -i -e "/<?php/a\\
Sometext" *.php \;
But it adds Sometext many times (instead of one) only in php files in the current directory (instead of all). What I did wrong?

You don't pass the files found by find to the sed command, but the files found by the shell glob *.php. Before find is executed, the *.php is expanded and your command becomes
find . -name '*.php' -exec sed ... 1stMatch.php 2ndMatch.php ... \;
Afterwards, find will for each found file execute the command
sed ... 1stMatch.php 2ndMatch.php ...
You probably wanted to write
find . -name '*.php' -exec sed -i -e '/<?php/a\\
Sometext' {} \;
For each file, find executes sed and replaces {} by one file name.
In this case, you could even write {} + instead of {} \; such that sed is executed only once on all files at once, instead of once for every file – this will speed up your command drastically.

Related

How can I remove empty lines in every file of a directory?

How can I remove empty /blank lines in every txt file of a directory (ideally subdirectories too)?
find . -name '*.txt' -exec ex '+%s/\ / /g' -cwq {} \;
Above code is pulling list of files correctly but i am not sure what regular expression to pass to remove blank lines.
With GNU find and GNU sed:
find . -name '*.txt' -exec sed -ri '/^\s*$/d' {} \;

Get all occurrences of a string within a directory(including subdirectories) in .gz file using bash?

I want to find all the occurrences of "getId" inside a directory which has subdirectories as follows:
*/*/*/*/*/*/myfile.gz
i tried thisfind -name *myfile.gz -print0 | xargs -0 zgrep -i "getId" but it didn't work. Can anyone tell me the best and simplest approach to get this?
find ./ -name '*gz' -exec zgrep -aiH 'getSorById' {} \;
find allows you to execute a command on the file using "-exe" and it replaces "{}" with the file name, you terminate the command with "\;"
I added "-H" to zgrep so it also prints out the file path when it has a match, as its helpful. "-a" treats binary files as text (since you might get tar-ed gzipped files)
Lastly, its best to quote your strings in case bash starts globbing them.
https://linux.die.net/man/1/grep
https://linux.die.net/man/1/find
Use the following find approach:
find . -name *myfile.gz -exec zgrep -ai 'getSORByID' {} \;
This will print all possible lines containing getSORByID substring

sed hanging with no results but rename works

find /$HOME/Desktop -name "*.dpx" -exec sed -i "" 's/Exile1/ExileR1/' {} \;
just hangs with no results. I'm unclear what the problem may be.
Buuuut,
find /$HOME/Desktop -name "*.dpx" -exec rename 's/Exile1/ExileR1/' {} \;
works fine.
Why????
I'm on MacOSX.
Given that you contrast your failing sed command with rename, it looks like you're trying to rename files, whereas the sed command would perform a string substitution in the content of the files you pass; the -i option then writes the modified input back to the input file (loosely speaking).
sed cannot rename files directly, but you can use it as an auxiliary command to construct a new filename you then pass to mv:
find "$HOME/Desktop" -name "*.dpx" -print0 |
while IFS= read -d '' -r file; do
echo mv "$file"' "$(sed 's/Exile1/ExileR1/' <<<"$file")"
done
Remove echo to perform actual renaming.
I don't have any .dpx files, but try adding a -e to clarify the search script. Like this...
find /$HOME/Desktop -name "*.dpx" -exec sed -i "" -e 's/Exile1/ExileR1/' {} \;

How to access all files in all sub directories using shell script?

I want to execute following command on all files of a directory and also on all files in sub directories of that directory:
cat filename | col -b > filename
this command will remove control M or ^M character from the file and works fine with single file. Please help ...
I tried below command but doesn't work. It works with single directory but not with sub directories.
for i in *
do
cat i | col -b > i
done
find . -type f -name '*.gif or .jpeg' -o -exec sed -i 's/^M//' {} \;
this is what your looking for ^M it works in all file to remove the images. just check it in you are code
find . -type f -exec sed -i 's/^M//' {} \;
Note, do the ^M by hitting ctrl-V then ctrl-m, not just ^M
If you want to only hit a subset of files, then specify an appropriate regexp and pass that to find as (most likely) -iname - see man find for the options

Removing files with a double quote in their name

I am trying to remove files within a directory. Some of the files have double-quotes around their name while others do not. An example of these files would be:
"DDD344".csv
D2DW.csv
Both these files are located in sub-directories within the directory YM.
To find such files and remove them, I invoke find like so:
find YM -name "*.csv" -print | xargs rm
The above command results in a lot of No such file or directory errors.
I tried using sed in the following way:
find yum/yum_hyd -name "\"*\".csv" | sed 's/"/\"/g' | xargs rm
but to no avail. How do I remove the files?
The problem is that you're using xargs. xargs is a horribly broken program that should never be used for anything except in conjunction with the nonstandard -0 option. Even so, I can't think of any advantages to doing that in this case. You should just execute rm directly from find.
find . -type f -name '"*".csv' -exec rm -f -- {} +
Will work. If you have GNU find, you may also use -delete.
try this:
find yum/yum_hyd -name "\"*\".csv" |sed 's/"/\\"/g'|xargs rm
explanation:
you want to replace " with \". but if you write \" directly, sed considers it as plain ", you have to escape the backslash. so \\" works.
I wasn't aware of this option until recently but you can list the inode of the file in the following way:
$ ls –il
In the output you will see that the first column contains the inode value. You can then use that value to find -inum the offending files and remove them.
Output
2616366 -rw-r--r-- 1 etc etc
$ find . -inum 2616366 -exec rm -f {} \;
This will remove the file with that specific inum.
As a test you can run the following to locate your files.
ls -il \"* | awk '{print $1}' | xargs -n1 -I {} find -inum {}
Replace the final portion of this command (the "find -inum {}") with the "rm" command once you are satisfied.
This is also similar to the question on SuperUser

Resources