Rename all files in directory [duplicate] - linux

This question already has answers here:
Argument list too long error for rm, cp, mv commands
(31 answers)
Closed 8 years ago.
I'm trying to rename the files like:
Name1_searchstats_metrics_20141230T133000036.log
to something like: Name2_searchstats_metrics_20141230T133000036.log
I'm trying: rename -n 's/\Name1_/\Name2_/' *.log but am getting the error:
bash: /usr/bin/rename: Argument list too long
Can someone please help ?

probably the easiest solution, since you're using bash is to iterate over the list of files with a for loop:
$ for i in *; do rename -n 's/Name1_/Name2_/' $i; done
you can also filter the files if needed by using any wildcard in the command, like *.log.
There are other more convoluted ways to achieve this, especially if you need to do particular string manipulation of the file name, i.e. using awk or find -exec, but hopefully this could help you sort things out in a clear way.
Edited answer as suggested by #glglgl
a more comprehensive and detailed explanation of the above can be found on superuser:
https://superuser.com/questions/31464/looping-through-ls-results-in-bash-shell-script

If the argument list is too long for a linux command, xargs usually comes to the rescue.
Try this:
ls *.log | xargs rename -n 's/\Name1_/\Name2_/'

Related

Writing a bash script to find all files in a directory that start with a, and do nothing if one exist [duplicate]

This question already has answers here:
Do not show results if directory is empty using Bash
(3 answers)
Closed 4 years ago.
So I have to find all the files in the directory that start with the letter a, and list them out. This is pretty easy by doing
cd some_directory
for file in a*; do
echo "$file"
done
However I want that if there are no files present that match a*, then the for loop will not run at all. Currently, if this is the case then the shell will echo
a*
Is there a way to do this? Thank you
Your text is opposite of your title, in my answer below I've assumed the text is your intention and your title is incorrect:
globs can be made to act like this with the bash shell option "nullglob":
shopt -s nullglob
An alternative is to use find and ignore errors by piping stderr to /dev/null
for file in $(find a* 2>/dev/null); do
echo "$file"
done

Create symlink of every file in a folder tree [duplicate]

This question already has answers here:
symlink-copying a directory hierarchy
(7 answers)
Closed 4 years ago.
I need a Bash script that will create a symlink for every *.mp3 file in folder X (and its subfolders), and store those symlinks in folder Y, without subfolders and probably skipping duplicates.
For the curious, this is to automate a radio station using Libretime.
And sorry if this is a dumb question, I never used a Bash script.
As in the comment: use find to create a list of the mp3-files:
find /top/dir/for/mp3s -name '*mp3'
You will want to use that output to loop over it, so:
find /top/dir/for/mp3s -name '*mp3' | while read mp3file, do
# do the linking
done
You want create a link in a specific directory, probably with the same filename. You can get the filename with basename. So, that would make it something like this:
find /top/dir/for/mp3s -name '*mp3' | while read mp3file; do
filename=$(basename $mp3file)
ln -s $mp3file /dir/where/the/links/are/$filename
echo Linked $mp3file to /dir/where/the/links/are/$filename
done
However, this will probably give you two types of error:
If the mp3 filename contains spaces, basename will not produce the correct filename and ln will complain. Solution: use correct quoting.
If you have duplicate filenames, ln will complain that the link already exists. Solution: test if the link exists.
Because you're not destroying anything, you can try it and actually see the problems. So, our next iteration would be:
find /top/dir/for/mp3s -name '*mp3' | while read mp3file; do
filename=$(basename "$mp3file")
if [ ! -l "/dir/where/the/links/are/$filename" ] ; then
ln -s "$mp3file" "/dir/where/the/links/are/$filename"
echo "Linked $mp3file to /dir/where/the/links/are/$filename"
else
echo "Not linked $mp3file; link exists"
fi
done
That should give you a fairly good result. It also gives you a good starting point.

shell script to list file names alone in a directory & rename it [duplicate]

This question already has answers here:
How can I remove the extension of a filename in a shell script?
(15 answers)
Closed 6 years ago.
I'm new to scripting concept.. I have a requirement to rename multiple files in a directory like filename.sh.x into filename.sh
First I tried to get the file names in a particular directory.. so i followed the below scripting code
for entry in PathToThedirectory/*sh.x
do
echo $entry
done
& the above code listed down all the file names with full path..
But my expected o/p is : to get file names alone like abc.sh.x,
so that I can proceed with the split string mechanism to perform rename
operation easily...
help me to solve this ... Thanks in advance
First approach trying to follow OP suggestions:
for i in my/path/*.py.x
do
basename=$(basename "$i")
mv my/path/"$basename" my/path/"${basename%.*}"
done
And maybe, you can simplify it:
for i in my/path/*.py.x
do
mv "$i" "${i%.*}";
done
Documentation regarding this kind of operation (parameter expansion): https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html
In particular:
${parameter%word} : The word is expanded to produce a pattern just as in filename expansion. If the pattern matches a trailing portion of the expanded value of parameter, then the result of the expansion is the value of parameter with the shortest matching pattern (the ‘%’ case) or the longest matching pattern (the ‘%%’ case) deleted
So, ${i%.*} means:
Take $i
Match .* at the end of its value (. being a literal character)
Remove the shortest matching pattern
Look into prename (installed together with the perl package on ubuntu).
Then you can just do something like:
prename 's/\.x$//' *.sh.x
In ksh you can do this:
for $file in $(ls $path)
do
new_file=$(basename $path/$file .x)
mv ${path}/${file} ${path}/${new_file}
done
This should do the trick:
for file in *.sh.x;
do
mv "$file " "${file /.sh.x}";
done
Running this rename command from the root directory should work:
rename 's/\.sh\.x$/.sh/' *.sh.x
for i in ls -la /path|grep -v ^d|awk '{print $NF}'
do
echo "basename $i"
done
it will give u the base name of all files or you can try below
find /path -type f -exec basename {} \;

How to rename files without changing extension in Linux 102221.pdf to 102221_name.pdf

How to rename files without changing extension in Linux \
102221.pdf to 102221_name.pdf
This is what you want I think:
for x in *; do mv "$x" "${x%.*}_name.${x##*.}"; done
${x%.*} will give the name of the file without extention
${x##*.} will extract the extentions
ls * | sed -r 'p;s/\.pdf$/_name\.pdf/g' | xargs -n2 mv
list all the files with ls and pipe the output to sed. sed replaces .pdf with _name.pdf and outputs both the original file name and the new file name to xargs with will call mv with the 2 parameters.
you can also use the rename command which is simpler
rename 's/\.pdf$/_name\.pdf/g' ./*
The regex pattern remains the same though
well i am not so good in linux.. but still found a working answer for you.. hope it will solve ur purpose..
check the given link.. you might need a light weighted tool called as jhead mainly its to get the header information about the file link created date and time and other.. you can find the information which suits you..
Answer
https://superuser.com/questions/90057/linux-rename-file-but-keep-extension
jhead
http://www.sentex.net/~mwandel/jhead/

Best way to find the numeric value in UNIX file system [duplicate]

This question already has answers here:
How to find all files containing specific text (string) on Linux?
(54 answers)
Closed 8 years ago.
I need to grep for a particular port number from a huge set of files.
I am using a command:
find . |xargs grep "9461"
But it does not finds all the occurrences for number 9461.
Can anyone suggest a better unix/linux command to do so.
The kind of files it gets is : x.log, y.txt,z.htm, a.out etc files
But it was not able to get abc.conf files
You surely have some reason for using find in combination with grep, but just in case:
You can replace your command by:
grep -r "9461" .
and if you want even line numbers
grep -rn "9461" .
As JonathanLefflero commented, there is also the option -e that make grep match againt a regular expression, so, the ultimate command would be
grep -rne 9461
You should take a look on grep man page
A final note, you should check if what you want to grep is "9461" or 9461 without "".

Resources