Bash, sed, awk
How to clean bash history
history -cw
Copy retaining subfolder structure
find -name "*.svg*" -exec cp --parents --no-dereference {} Vector/ \;
Replace pattern in file names
for i in *.txt; do if $i =~ Tivoli ; then mv "$i" "$(echo $i | sed -n s/Changethis/Tothat/p)"; fi; done
How to go up and down shell history
Up is Ctrl-R, down is Ctrl-S but there is a conflict with kde's xon/xoff. You need to disable it but only for interactive shells, so scp etc is not affected.
Add the following to .bashrc, or .bash_profile (for interactive logins)
$- == *i* && stty -ixon
Mass Rename
for i in *.avi; do mv "$i" "${i%.avi}.dv"; done
How to remove non-ascii characters from a file
tr -cd '\11\12\15\40-\176' < infile > outfile
How to convert text to lower or upper case
cat instances-stage | tr [:lower:] [:upper:]
How to lowercase text with sed
Regexp's \L in front of a parameter is the lowercaser, \U is the uppercaser
sed -ri 's/(\W|^)somestuff(\w*)/\1somestuff\L\2/g' text.file
How to remove blank lines
sed '/^\s*$/d' File.in > File.out
How to use SED regexp with a non-greedy qualifier
sed does not have it. Use an exclusion format [^ ] to terminate match early like this
echo "http://dada.do/dadad" | sed -rne 's|\/[^/]*\/|\1|gp'
or use perl that supports it
echo "http://dada.do/dadad" | perl -pe 's|\/.*?\/|\1\|'
or awk using a split
string="http://www.dada.da/baba/16/" echo $string | awk -F"/" '{print $1,$2,$3}' OFS="/"
How to watch for file change and run command
while true; do inotifywait -r -e MODIFY dir/file && your-command done
How to move single files to higher directory
for just the current folder
# captial A to avoid . and ..
for i in *; do if [[ -d $i && $(ls -Al "$i" | grep -v ^total | wc -l) -eq 1 ]]; then echo $(ls "$i"/*); mv "$i"/* . ; fi; done;
for all folders recursively
this also renames the file with the name of the folder it contains. May cause some files to be really long
find -type d -exec bash -c 'if grep -v ^d | grep -v ^total | wc -l) -eq 1 ; then fn=$(ls "$1/"); if -f "$1/$fn" ; then if $fn == $(basename "$1")* ; then nn=$(dirname "$1")/$fn; else nn="$1 - $fn"; fi; echo mv "$1/$fn" "$nn" ; fi; fi; ' _ {} \;
the first if checks that the number of files (not folders, total, . or .. (ls -A)) is 1.
Then checks that the single item in the folder is a file, not another folder
Then it checks if the file's name already starts with the parent folder name. If it does it will not prepend it, otherwise it adds the name of the parent folder to the file name
Then it moves up the file.
note that in a rare case that the file has exactly the same name as the parent folder, the move will fail.
after running the line above you will need to remove empty folders and re-run the recursive thingy again, in case there is one files in a folder in a folder in a folder etc.
To clean empty folders run:
find -type d -empty -delete
How extract multiple matches from a single line
Use perl because sed does not have a non-greedy modifier. To make sure only matching lines are printed and mimic sed behavior use perl -n (the opposite of -p) and "print if" function.
Here is an example of how to match, extract and create a downloader script from an html, to get all images linked from a page:
perl -ne 'print if s/.*?href="(.*?\.jpg)".*?alt="(.*?)".*?/curl -o "\2.jpg" "\1"\n/g' < Desktop\ backgrounds\ -\ Microsoft\ Windows.html > download.sh
How to find files that don't have the group read permission set
Use the negation combined with an "or" for file permission attributes
sudo find . -type f ! -perm /077 -ls
Would find all files that dont have a single bit set in either group or other permission attribute, regardless of what is in the users's attribute.
How to use xargs with quoting for file names with spaces
Use xarg substitution like this:
file * | egrep "\bdata$" | awk -F ":" '{print $1}' | xargs -I{} rm -v {}
The command above kills all unknown files in the folder, last part functions similarly to find's {}
How to use bash parameter substitution and other functions inside find exec
Call bash -c with a parameter:
find . -name "*.mp4" -exec bash -c 'rm -v "${0%.mp4}.avi"' "{}" \;
In this case the command removes all .avi files that have a similarly named .mp4 file
How to join lines in a file or match patterns that span multiple lines
Joining every two lines. Change the subst pattern to also do some work on the joined lines
sed 'N;s/\n//' yourFile
Delete everything between "ONE" and "TWO" if they are on one or two consecutive lines:
sed '/ONE/ { # append the next line N # look for "ONE" followed by "TWO" /ONE.*TWO/ { # delete everything between s/ONE.*TWO/ONE TWO/ # print P # then delete the first line D } }' file
Inserting a new line. Don't use "\n" - instead insert a literal new line character:
(echo a;echo x;echo y) | sed 's:x:X\ :'
More details here
How to find all files in subdirectories containing a string
find . -name "*.jsp" | xargs grep "login b"
How to get a list of files with atypical owners
sudo ls -AlR / | grep -v -E 'root|total|www-data|/|^$'
How to get directory sizes in the current folder
ls -d \* | xargs -i du -kasm {}
How to get size of folders in the current folder
ls | xargs du -sh
or
du -sh `ls`
Note - does not work for folders with spaces in the name, escape with sed 's/\s/\\ /'
How to make a command survive term or putty or xterm termination
Just running it with ampersand wont work First run it with ampo
./command &
then disown it
disown [process number]
where process number is the process number from the previous command (or you can get it by doing ps -ef | grep [command])
disown is a bash command to detach the child-process from the parent and allow it to run "freely" (actually, it changes the parent to whatever is farther up the process chain).
Another handy way of doing this is the nohup command. This will even further detach the given command to "survive" even a full logout - which is not recommended for UI programs. It's used quite a bit in the system services at startup.
How to search for relevant man pages
apropos [substring]
How to perform a mass rename of files
Use rename regex in conjunction with find. For example to strip off a pattern:
find . -name "*pattern*" -exec rename -n -v 's|^(.*/)(.*) pattern (.*)\s*$|$1$2$3|g' {} \;
How to extract data with bash
Just an example of getting data with bash commands
df -h | awk '{print $5}' | grep % | grep -v Use | sort -n | tail -1 | cut -d "%" -f1 -
This will show the topmost utilization of a mounted linux partition.
How to iterate over lines in a file with bash
while read i; do touch "$i"; done < ../list
How to change permissions on all files that have a certain other set of permissions (or type or name)
file . -perm 600 | sed -n "s/$.*$/\"\1\"/gp" | xargs chmod 600
How to pipe gunzip into tar for on the fly unpacking
If your tar supports it run
tar zxvf file.tar.gz
otherwise do
gunzip -c file.tar.gz | tar -xvf -
How to set default shell to bash in Makefiles under Ubuntu
Add the following at the top of each file:
SHELL = /bin/bash
How to set a prompt to use current folder
export PS1="`whoami`@`hostname`"'($PWD)# '
How to set display variable automagically in .profile
D1=`who am i| awk '{print substr($6,2,(length($6)-2))}'`
if [ -z "$D1" ]
then
D1=`hostname`
fi
D2=`echo $D1 | awk '{print index($1,":")}'`
if [ $D2 -gt 0 ]
then
export DISPLAY=$D1
else
#display=`host $D1 | awk '{print $3}'`
display=$D1
export DISPLAY=${display}:0.0
echo "DISPLAY Set to: ${display}:0.0"
fi
How to reinforce directory and file access limits
find . -perm /077 -type d -exec chmod -v 700 {} \; find . -perm /077 -type f -exec chmod -v o-rwx,g-rwx {} \;
How to cp (copy) in a command line with a progress indicator
rsync -Pacz source destination
This will copy the metadata as well. If you want it to use the new date/time/owner, just like cp does, run the following. Note though that running this twice will copy the files twice unless you add the -c switch for checksumming files.
rsync -ghop --progress source destination
How to do a mass search and replace
Following is a handy little command to get the job done. Assuming you are in the directory where you want to effect this search/replace --
perl -pi -e 's/lookFor/replaceWith/' *.fileExtension perl -pi -e 's/lookFor/replaceWith/g' *.fileExtension perl -pi -e 's/lookFor/replaceWith/gi' *.fileExtension
NOTES: - lookFor is the word you wish to look for. - replaceWith is the word you wish to replace your original word with - g stands for global, it will basically replace all the occurences of lookFor with replaceWith in all your files in a directory - i stands for case insensitive
To load a series of replace expressions from a text file:
perl -pi -e /path/to/replace-patterns.txt *.fileExtension
where replace-patterns.txt looks like (don't forget the semicolon!):
s/lookForPatternOne/replaceWithOne/; s/lookForPatTwo/replaceWithTwo/g; s/lookForPatThree/replaceWithThree/gi;