for all file names with .sh - bash

it should display only the file names without the.sh
Example
$>./file.sh | cat -e

you can do :
find . -maxdepth 1 -type f -name \*.sh | sed 's|.sh$||'
remove the maxdepth 1 option if you want to find all the files recursively

You can just do ls | grep -v .sh to find in the current directory.
-v, --invert-match
Invert the sense of matching, to select non-matching lines.
If you need system-wide search, you'll need find:
find / -type f ! -name "*\.sh"
/ means root folder
type f = file
! -name = not sending with .sh

Related

How to write the wc's stdout into a file?

The below command will show how many characters contains in every file in current directory.
find -name '*.*' |xargs wc -c
I want to write the standout into a file.
find -name '*.*' |xargs wc -c > /tmp/record.txt
It encounter an issue:
wc: .: Is a directory
How to write all the standard output into a file?
Why -name '*.*'? That will not find every file and will find directories. You need to use -type f, and better than piping the result to xargs is using -exec:
find . -type f -maxdepth 1 -exec wc -c {} + > /tmp/record.txt
-maxdepth 1 guarantees that the search won't dive in subdirectories.
I think you maybe meant find |xargs wc -c?
find -name '.' just returns .
Filter only files, if you want only files.
find -type f

I want to grep a pattern inside a file n list that file based on current date

ls -l | grep "Feb 22" | grep -l "good" *
This is the command i am using . i have 4 files among which one file contains the world good . I want to list that file . And that file creation is the current date . based on both the criteria i want to list that file
Try this :
find . -type f -newermt 2018-02-21 ! -newermt 2018-02-22 -exec grep -l good {} \;
or
find . -type f -newermt 2018-02-21 ! -newermt 2018-02-22 | xargs grep -l good
And please, don't parse ls output
Hi Try with below command. How it works? Here find command with parameter -mtime -1 will search for files with current date in current directory as well as its sub directories. Each file found will be pass to grep command one at a time. grep command will check for the string in that file (means each file passes to it)
find . -mtime -1 -type f | xargs grep -i "good"
In the above command it will list all the file with current date. To list a files of specific kind you below command. Here I am listing only txt files.
find . -name "*.txt" -mtime -1 -type f | xargs grep -i "good"
find . is for running it from current directory (dot means current directory). To run it from a specific directory path modify like below:-
find /yourpath/ -name "*.txt" -mtime -1 -type f | xargs grep -i "good"
Also grep -i means "ignore case". For a specific case just use grep "good"

bash find change name file for directory name 2 levels up

Hello and thanks for reading!
I have list like that:
user#laptop:~/lol$ find ./ \( -iname 'latest*' \) -type f -printf "%p\n"
/leagueoflegends/images/e/e6/CaitlynSquare.png/revision/latest?cb=20150402215548
/leagueoflegends/images/e/ef/WillumpSquare.png/revision/latest?cb=20150402222523
/leagueoflegends/images/d/d8/MorganaSquare.png/revision/latest?cb=20150402220702
/leagueoflegends/images/d/d1/UdyrSquare.png/revision/latest?cb=20150402221631
(its longer) and I want to copy each image ("latest?cb=20150402221631" are png images) to another folder and rename it for the name of 2 level up directory, like this:
latest?cb=20150402221631 --> to --> UdyrSquare.png
And if its possible, remove Square.
latest?cb=20150402221631 --> to --> Udyr.png
With bash:
Append this:
| while read -r line; do echo mv -v "$line" "${line%Square*}.png"; done
If everything looks okay, remove echo.
If you have the Perl rename command (which maybe prename or perl-rename on your distribution), you can use regular expressions to rename files. It can read filenames from input:
find . -iname 'latest*' -type f | rename -n ':Square.png.*cb=\d+:.png:'
Or, more specifically:
find . -iname 'latest*' -type f | rename -n 's:Square.png/[^/]*/latest\?cb=\d+:.png:'
For example:
$ cat foo.txt| perl-rename -n 's:Square.png/[^/]*/latest\?cb=\d+:.png:'
/leagueoflegends/images/e/e6/CaitlynSquare.png/revision/latest?cb=20150402215548 -> /leagueoflegends/images/e/e6/Caitlyn.png
/leagueoflegends/images/e/ef/WillumpSquare.png/revision/latest?cb=20150402222523 -> /leagueoflegends/images/e/ef/Willump.png
/leagueoflegends/images/d/d8/MorganaSquare.png/revision/latest?cb=20150402220702 -> /leagueoflegends/images/d/d8/Morgana.png
/leagueoflegends/images/d/d1/UdyrSquare.png/revision/latest?cb=20150402221631 -> /leagueoflegends/images/d/d1/Udyr.png
The -n option is for testing the command. Once you are satisfied with the results, run without it.

Rename all files in subfolders - replace string in filename

I want to rename all files in a folder and its subfolders.
I need to change the string HEX20 to the string HEX8.
Some filenames have other numbers, so I cannot simply change the 20 to an 8.
An example of the full path is:
\\FRDS01006\z188018\FEM\Linear\HEX20\3HEX20\3HEX20.bof
I would like to do the same replacement for the folder names.
How about this:
find . -name "*HEX20*" -exec rename HEX20 HEX8 '{}' +
This will search recursively through the current directory and any subdirectories to match HEX20. (The flag -type f is omitted because the asker wants to change the names of directories in addition to files.) It will then build a long rename command and ultimately call it. This type of construction may be simpler than building a series of commands with sed and then executing them one-by-one.
Try this:
find . -type f -name "*HEX20*" | sed 's/\(.*\)HEX20\(.*\)/mv \0 \1HEX8\2/' | sh
This way you find for regular files having HEX20 in their names:
find . -type f -name "*HEX20*"
then change the last occurrence of HEX20 whith HEX8 and compile the mv command:
find . -type f -name "*HEX20*" | sed 's/\(.*\)HEX20\(.*\)/mv \0 \1HEX8\2/'
finally you execute the compiled commands with sh:
find . -type f -name "*HEX20*" | sed 's/\(.*\)HEX20\(.*\)/mv \0 \1HEX8\2/' | sh

Terminal find, directories last instead of first

I have a makefile that concatenates JavaScript files together and then runs the file through uglify-js to create a .min.js version.
I'm currently using this command to find and concat my files
find src/js -type f -name "*.js" -exec cat {} >> ${jsbuild}$# \;
But it lists files in directories first, this makes heaps of sense but I'd like it to list the .js files in the src/js files above the directories to avoid getting my undefined JS error.
Is there anyway to do this or? I've had a google around and seen the sort command and the -s flag for find but it's a bit above my understanding at this point!
[EDIT]
The final solution is slightly different to the accepted answer but it is marked as accepted as it brought me to the answer. Here is the command I used
cat `find src/js -type f -name "*.js" -print0 | xargs -0 stat -f "%z %N" | sort -n | sed -e "s|[0-9]*\ \ ||"` > public/js/myCleverScript.js
Possible solution:
use find for getting filenames and directory depth, i.e find ... -printf "%d\t%p\n"
sort list by directory depth with sort -n
remove directory depth from output to use filenames only
test:
without sorting:
$ find folder1/ -depth -type f -printf "%d\t%p\n"
2 folder1/f2/f3
1 folder1/file0
with sorting:
$ find folder1/ -type f -printf "%d\t%p\n" | sort -n | sed -e "s|[0-9]*\t||"
folder1/file0
folder1/f2/f3
the command you need looks like
cat $(find src/js -type f -name "*.js" -printf "%d\t%p\n" | sort -n | sed -e "s|[0-9]*\t||")>min.js
Mmmmm...
find src/js -type f
shouldn't find ANY directories at all, and doubly so as your directory names will probably not end in ".js". The brackets around your "-name" parameter are superfluous too, try removing them
find src/js -type f -name "*.js" -exec cat {} >> ${jsbuild}$# \;
find could get the first directory level already expanded on commandline, which enforces the order of directory tree traversal. This solves the problem just for the top directory (unlike the already accepted solution by Sergey Fedorov), but this should answer your question too and more options are always welcome.
Using GNU coreutils ls, you can sort directories before regular files with --group-directories-first option. From reading the Mac OS X ls manpage it seems that directories are grouped always in OS X, you should just drop the option.
ls -A --group-directories-first -r | tac | xargs -I'%' find '%' -type f -name '*.js' -exec cat '{}' + > ${jsbuild}$#
If you do not have the tac command, you could easily implement it using sed. It reverses the order of lines. See info sed tac of GNU sed.
tac(){
sed -n '1!G;$p;h'
}
You could do something like this...
First create a variable holding the name of our output file:
OUT="$(pwd)/theLot.js"
Then, get all "*.js" in top directory into that file:
cat *.js > $OUT
Then have "find" grab all other "*.js" files below current directory:
find . -type d ! -name . -exec sh -c "cd {} ; cat *.js >> $OUT" \;
Just to explain the "find" command, it says:
find
. = starting at current directory
-type d = all directories, not files
-! -name . = except the current one
-exec sh -c = and for each one you find execute the following
"..." = go to that directory and concatenate all "*.js" files there onto end of $OUT
\; = and that's all for today, thank you!
I'd get the list of all the files:
$ find src/js -type f -name "*.js" > list.txt
Sort them by depth, i.e. by the number of '/' in them, using the following ruby script:
sort.rb:
files=[]; while gets; files<<$_; end
files.sort! {|a,b| a.count('/') <=> b.count('/')}
files.each {|f| puts f}
Like so:
$ ruby sort.rb < list.txt > sorted.txt
Concatenate them:
$ cat sorted.txt | while read FILE; do cat "$FILE" >> output.txt; done
(All this assumes that your file names don't contain newline characters.)
EDIT:
I was aiming for clarity. If you want conciseness, you can absolutely condense it to something like:
find src/js -name '*.js'| ruby -ne 'BEGIN{f=[];}; f<<$_; END{f.sort!{|a,b| a.count("/") <=> b.count("/")}; f.each{|e| puts e}}' | xargs cat >> concatenated

Resources