How do I make a tree of all things with bash? What is the command?
tree /
or
find /
Update: #OP, since you have so much trouble with it, how about this alternative. On ubuntu 9.10, you should have bash 4.0 ? so try this
#!/bin/bash
shopt -s globstar
for rdir in /*/
do
for file in $rdir/**
do
echo "$file"
done
done
you should probably alias this :)
ls -R | grep ":$" | sed -e 's/:$//' -e 's/[^-][^\/]*\//--/g' -e 's/^/ /' -e 's/-/|/'
(Warning: huge output)
$ find . -print | sed -e 's;/*/;|;g;s;|; |;g'
Add alias to ~/.bash_profile
alias tree="find . -print | sed -e 's;/*/;|;g;s;|; |;g'"
tree -R /
and then cry because it's enormous.
On a related note, to stop the command, press CTRL+C
Assuming you want to find something from tree, do
tree / > tree.txt
Then Ctrl + F it.
Related
I run this command to find and replace all occurrences of 'apple' with 'orange' in all files in root of my site:
find ./ -exec sed -i 's/apple/orange/g' {} \;
But it doesn't go through sub directories.
What is wrong with this command?
Here are some lines of output of find ./:
./index.php
./header.php
./fpd
./fpd/font
./fpd/font/desktop.ini
./fpd/font/courier.php
./fpd/font/symbol.php
Your find should look like that to avoid sending directory names to sed:
find ./ -type f -exec sed -i -e 's/apple/orange/g' {} \;
For larger s&r tasks it's better and faster to use grep and xargs, so, for example;
grep -rl 'apples' /dir_to_search_under | xargs sed -i 's/apples/oranges/g'
Since there are also macOS folks reading this one (as I did), the following code worked for me (on 10.14)
egrep -rl '<pattern>' <dir> | xargs -I# sed -i '' 's/<arg1>/<arg2>/g' #
All other answers using -i and -e do not work on macOS.
Source
This worked for me:
find ./ -type f -exec sed -i '' 's#NEEDLE#REPLACEMENT#' *.php {} \;
grep -e apple your_site_root/**/*.* -s -l | xargs sed -i "" "s|apple|orange|"
Found a great program for this called ruplacer
https://github.com/dmerejkowsky/ruplacer
Usage
ruplacer before_text after_text # prints out list of things it will replace
ruplacer before_text after_text --go # executes the replacements
It also respects .gitignore so it won't mess up your .git or node_modules directories (find . by default will go into your .git directory and can corrupt it!!!)
I think we can do this with one line simple command
for i in `grep -rl eth0 . 2> /dev/null`; do sed -i ‘s/eth0/eth1/’ $i; done
Refer to this page.
In linuxOS:
sed -i 's/textSerch/textReplace/g' namefile
if "sed" not work try :
perl -i -pe 's/textSerch/textReplace/g' namefile
Under my folder, there are a lot of files all starting with "abcd", like "abcd****".
What I am going to do is change all the files names replacing "abcd" by "xyz".
How to use shell command like "find" "sed" to do this?
A simple method would be something like this:
for i in abcd*; do mv "$i" "xyz${i#abcd}"; done
Using a combination of ls, sed and xargs you could use:
ls * | sed -e 'p;s!^abcd!xyz!' | xargs -n2 mv
Result:
abcd.png → xyz.png
* to do a dry-run first, replace mv at the end with echo
for f in abcd*; do mv "$f" "$(echo "$f" | sed 's/^abcd/xyz/g')"; done
I am using the following command on command line for getting the pattern matched lines.
find . -name "*.gz"|xargs gzcat|grep -e "pattern1" -e "pattern2"
i need now to find only the file names where the pattern is present.
how can i do it on command line?
grel -l has no use since i am using xargs gzcat before grep
Check if you have zgrep available. And then, if yes:
find . -name '*.gz' -exec zgrep -l -e ".." -e ".." {} +
If you don't have it - well, just copy it from some machine that has it (all linuxes I use have it by default) - it's a simple bash script.
ripgrep
Use ripgrep, for example, it's very efficient, especially for large files:
rg -z -e "pattern1" -e "pattern2" *.gz
or:
rg -z "pattern1|pattern2" .
or:
rg -zf pattern.file .
Where pattern.file is a file containing all your patterns separated by a new line character.
-z/--search-zip Search in compressed files (such as gz, bz2, xz, and lzma).
for i in $(find . -name "*.gz"); do gzcat $i|grep -qe "n1" -e "n2" && echo $i; done
Untested; does everything inside find so if you have loads of gz files you wont have performance problems as runs each gzcat/grep as soon as it finds files nothing is piped out:
find . -iname '*.gz' -exec bash -c 'gzcat $1 | grep -q -e "pattern1" -e "pattern2" && echo $1' {} {} \;
In bash, I'd do something like this (untested):
find . -name '*.gz' | while read f ; do gzcat $f | grep -q -e "pattern1" -e "pattern2" && echo $f ; done
grep/zgrep/zegrep
Use zgrep or zegrep to look for pattern in compressed files using their uncompressed contents (both GNU/Linux and BSD/Unix).
On Unix, you can also use grep (which is BSD version) with -Z, including -z on macOS.
Few examples:
zgrep -E -r "pattern1|pattern2|pattern3" .
zegrep "pattern1|pattern2|pattern3" **/*.gz
grep -z -e "pattern1" -e "pattern2" *.gz # BSD/Unix only.
Note: When you've globbing option enabled, ** checks the files recursively, otherwise use -r.
-R/-r/--recursive Recursively search subdirectories listed.
-E/--extended-regexp Interpret pattern as an extended regular expression (like egrep).
-Z (BSD), -z/--decompress (BSD/macOS) Force grep to behave as zgrep.
I'm trying to rename all files in current directory such that upper case name is converted to lower. I'm trying to do it like this:
ls -1|gawk '{print "`mv "$0" "tolower($0)"`"}'|xargs -i -t eval {}
I have two files in the directory, Y and YY
-t added for debugging, and output is:
eval `mv Y y`
xargs: eval: No such file or directory
if I execute the eval on its own, it works and moves Y to y.
I know there are other ways to achieve this, but I'd like to get this working if I can!
Cheers
eval is a shell builtin command, not a standalone executable. Thus, xargs cannot run it directly. You probably want:
ls -1 | gawk '{print "`mv "$0" "tolower($0)"`"}' | xargs -i -t sh -c "{}"
Although you're looking at an xargs solution, another method to perform the same thing can be done with tr (assuming sh/bash/ksh syntax):
for i in *; do mv $i `echo $i | tr '[A-Z]' '[a-z]'`; done
If your files are created by creative users, you will see files like:
My brother's 12" records
The solutions so far do not work on that kind of files. If you have GNU Parallel installed this will work (even on the files with creative names):
ls | parallel 'mv {} "$(echo {} | tr "[:upper:]" "[:lower:]")"'
Watch the intro video to learn more: http://www.youtube.com/watch?v=OpaiGYxkSuQ
You can use eval with xargs like the one below.
Note: I only tested this in bash shell
ls -1| gawk '{print "mv "$0" /tmp/"toupper($0)""}'| xargs -I {} sh -c "eval {}"
or
ls -1| gawk '{print "mv "$0" /tmp/"toupper($0)""}'| xargs -I random_var_name sh -c "eval random_var_name"
I generally use this approach when I want to avoid one-liner for loop.
e.g.
for file in $(find /some/path | grep "pattern");do somecmd $file; done
The same can be written like below
find /some/path | grep "pattern"| xargs -I {} sh -c "somecmd {}"
I have a renamed js file which I have to call in each of my php pages. Now I want to replace that old name with the new one using shell.
what iam using is this:
sed -i ’s/old/new/g’ *
but this is giving the following error:
sed: -e expression #1, char 1: unknown command:
How can I do this replacement?
sed -i.bak 's/old/new/g' *.php
to do it recursively
find /path -type f -iname '*.php' -exec sed -i.bak 's/old/new/' "{}" +;
There are probably less verbose solutions, but here we go:
for i in *; do sed -i 's/old/new/g' "$i"; done
Mind you, it will only work on the current level of the file system, files in subdirectories will not be modified. Also, you might want to replace * with *.php, or make backups (pass an argument after -i, and it will make a backup with the given extension).
this one is very simple, without for or loop, and takes care of any number or nested directories
grep -rl 'oldText' [folderName-optional] | xargs sed -i 's/oldText/newText/g'
You are using Unicode apostrophes (RIGHT SINGLE QUOTATION MARK - U2019) instead of ASCII (0x27) apostrophes around your sed command argument.
I know I'm really late but still:
find . -type f -name "*.php"|xargs sed -i 's/old/new/g'
perl -pi -e 's/old/new/g' *.php
For completeness, providing the OSX compatible version of the above accepted answer (to answer comment from #jamescampbell)
for i in *.php; do sed -i .orig 's/old/new/g' "$i"; done
This command creates .orig backup files.
Try this:
ls | grep "php" > files.txt
for file in $(cat files.txt); do
sed 's/catch/send/g' $file > TMPfile.php && mv TMPfile.php $file
done