Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
I'm looking for a way to recursively find files with extension X (.js) and make a copy of the file in the same directory with extension Y (.ts).
e.g. /foo/bar/foobar.js --> /foo/bar/foobar.js and /foo/bar/foobar.ts
/foo/bar.js --> /foo/bar.js and /foo/bar.ts etc etc
My due diligence:
I was thinking of using find & xargs & cp and brace expansion (cp foobar.{js,ts}) but xargs uses the braces to denote the list of files passed from xargs. This makes me sad as I just recently discovered the awesome-sauce that is brace expansion/substitution.
I feel like there has to be a one-line solution but I'm struggling to come up with one.
I've found ideas for performing the task: copying the desired to a new directory and then merging this directory with the new one; recursively run a renaming script in each directory; copy using rsync; use find, xargs and cpio.
As it stands it appears that running a renaming script script like this is what I'll end up doing.
find . -name "*.js" -exec bash -c 'name="{}"; cp "$name" "${name%.js}.ts"' \;
Using find, you can execute a command directly on a file that you've found, by using the -exec option; you don't need to pipe it through xargs. It takes the command name followed by arguments to the command, followed by a single argument ;, which you have to escape to avoid the shell interpreting it. find will replace any occurrence of {} in the command name or arguments with the file found.
In order call a command with the appropriate ending substituted, there are multiple approaches you can take, but a simple one is to use Bash's parameter expansion. You need to define a shell parameter that contains the name (in this case, I creatively chose name={}), and then you can use parameter expansion on it. ${variable%suffix} strips off suffix from the value of $variable; I then add on .ts to the end, and have the name I'm looking for.
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
My code is meant to find a /jar folder , loop through the .jar files and create .xml and .trigger files with the same file name. Additionally, it creates an ~ID~ filename ~ID~ field within the XML file.
I am getting the error
mkdir: cannot create directory '': No such file or directory
I have the /tmp folder set up, including an /xml /jar and /trigger folder, so those not being there isn't the issue.
#!/bin/bash
jar_dir= /c/Users/hi/Desktop/Work/tmp/jar
xml_dir= /c/Users/hi/Desktop/Work/tmp/xml
trigger_dir= /c/Users/hi/Desktop/Work/tmp/trigger
# the following creates output directories if they don't exist
mkdir -p "${xml_dir}"
mkdir -p "${trigger_dir}"
# we start the for loop through all the files named `*.jar` located in the $jar_dir directory
for f in $(find ${jar_dir} -name "*.jar")
do
file_id=$(basename -s .jar ${f}) # extract the first part of the file name, excluding .jar
echo "<ID>${file_id}</ID>" > ${xml_dir}/${file_id}.xml
touch ${trigger_dir}/${file_id}.trigger # this one just creates an empty file at ${trigger_dir}/${file_id}.trigger
done
This command:
jar_dir= /c/Users/hi/Desktop/Work/tmp/jar
is exactly equivalent to
jar_dir="" /c/Users/hi/Desktop/Work/tmp/jar
and tells the shell to run the command /c/Users/hi/Desktop/Work/tmp/jar with the environment variable jar_dir set to the empty string (only for the duration of that command). If /c/.../jar is a directory, that should give you an error, too.
To assign the /c/.../jar string to the variable instead, lose the space.
The error message you get comes from mkdir trying to create a directory with an empty name. (It's a bit confusing though.)
For problems with shell scripts, it often helps to paste the script to https://www.shellcheck.net/, which recognizes most of the usual mistakes and can tell what to do.
See these posts on SO and unix.SE for discussion:
Command not found error in Bash variable assignment
Is it shell portable to run a command on the same line after variable assignment?
Spaces in variable assignments in shell scripts
xml_dir= /c/Users/hi/Desktop/Work/tmp/xml
Can't have a space after the equal. So
xml_dir=/c/Users/hi/Desktop/Work/tmp/xml
This question already has answers here:
Rename multiple files based on pattern in Unix
(24 answers)
Closed 2 years ago.
I have a folder containing a sequence of files whose names bear the form filename-white.png. e.g.
images
arrow-down-white.png
arrow-down-right-white.png
...
bullets-white.png
...
...
video-white.png
I want to strip out the -white bit so the names are simply filename.png. I have played around, dry run with -n, with the Linux rename command. However, my knowledge of regexes is rather limited so I have been unable to find the right way to do this.
If you are in the directory above images, the command is
rename "s/-white.png/.png/" images/*
If your current directory is images, then run rename "s/-white.png/.png/" ./* instead. To do a dry run, just attach a -n like you said:
rename -n "s/-white.png/.png/" images/*
or
rename -n "s/-white.png/.png/" ./*
Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
i have been looking all throughout the google for the explanation of such commands
find /tmp -name core -type f -print | xargs /bin/rm -f
well i got the command from the net itself and explanation was also mentioned there.by now i know that this command is used to find a file named 'core' in the directory named 'tmp' and delete the file. i have used and checked this and it is perfectly working.
my problem is that i could not understand the terms used in this command like what does -type f, and xargs do??
also how to generate such commands according to our need(obviously could not unless properly understood), and the biggest problem is what to write in google to get the help regarding this...i mean under what topic may i expect these.
please help
regards.
This is a string of unix commands:
find // name of command (in this case, "find")
arguments to 'find':
/tmp // where to look
-name core // name to look for, "core" (optional argument)
-type f // files only (not, eg, directories or files contents)
// (optional argument)
-print // output the list to standard output (STDOUT)
| // name of command (otherwise known as
// 'pipe') this is a little program that
// takes the output from a previous process
// (in this case, the output from 'find')
// and pass it to another process as input
xargs // name of command ('xargs') the program
// that will accept the output from 'print'
// as input (directed by 'pipe'). It provides
// a robust way to process indefinitely
// long lists by breaking them into smaller
// lists and passing each sublist through
// to its command argument
/bin/rm // name of command for xargs to execute
// on its input list ('rm' = remove)
-f // argument to rm, only remove files, not directories.
That's how unix works, it's made up of lots of little single-purpose programs with obscure 2-letter names that are devoted to a single task. You string these together to achieve more complex tasks.
The correct way to find out what any one command does is to use the 'man' command with the command name in question as argument, eg
man find
man xargs
man rm
You will get pages of detailed info describing each input option and output possibilities. A name like 'xargs' is also easy to google but understandably 'find' is not (maybe try 'unix find'). Many of them have Wikipedia pages...
Perhaps you should get a decent into guide to unix ...
This question already has answers here:
How can I recursively find all files in current and subfolders based on wildcard matching?
(19 answers)
Closed 1 year ago.
I'm on Ubuntu, and I'd like to find all files in the current directory and subdirectories whose name contains the string "John". I know that grep can match the content of the files, but I have no idea how to use it with file names.
Use the find command,
find . -type f -name "*John*"
The find command will take long time because it scans real files in file system.
The quickest way is using locate command, which will give result immediately:
locate "John"
If the command is not found, you need to install mlocate package and run updatedb command first to prepare the search database for the first time.
More detail here: https://medium.com/#thucnc/the-fastest-way-to-find-files-by-filename-mlocate-locate-commands-55bf40b297ab
This is a very simple solution using the tree command in the directory you want to search for. -f shows the full file path and | is used to pipe the output of tree to grep to find the file containing the string filename in the name.
tree -f | grep filename
use ack its simple.
just type ack <string to be searched>
Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
Consider two directories:
/home/user/music/flac
/media/MUSIC/flac
I would like the second directory (destination; a USB drive) to contain the same files and structure as the first directory (master). There are 3600+ files (59G in total). Every file is scanned using unison, which is painfully slow. I would rather it compare based on file name, size, and modification time.
I think rsync might be better but the examples from the man pages are rather cryptic, and Google searches did not reveal any simple, insightful examples. I would rather not accidentally erase files in the master. ;-)
The master list will change over time: directories reorganized, new files added, and existing files updated (e.g., re-tagging). Usually the changes are minor; taking hours to complete a synchronization strikes me as sub-optimal.
What is the exact command to sync the destination directory with the master?
The command should copy new files, reorganize moved files (or delete then copy), and copy changed files (based on date). The destination files should have their timestamp set to the master's timestamp.
You can use rsync this way:
rsync --delete -r -u /home/user/music/flac/* /media/MUSIC/flac
It will delete files in /media/MUSIC/flac (never on master), and update based on file date.
There are more options, but I think this way is sufficient for you. :-)
(I just did simple tests! Please test better!)
You can use plain old cp to copy new & changed files (as long as your filesystems have working timestamps):
cp -dpRuv /home/user/music/flac /media/MUSIC/
To delete files from the destination that don't exist at the source, you'll need to use find. Create a script /home/user/bin/remover.sh like so:
#!/bin/bash
CANONNAME="$PWD/$(basename $1)"
RELPATH=$(echo "$CANONNAME" | sed -e "s#/media/MUSIC/flac/##")
SOURCENAME="/home/user/music/flac/$RELPATH"
if [ ! -f "$SOURCENAME" ]; then
echo "Removing $CANONNAME"
rm "$CANONNAME"
fi
Make it executable, then run it from find:
find /media/MUSIC/flac -type f -execdir /home/user/bin/remover.sh "{}" \;
The only thing this won't do is remove directories from the destination that have been removed in the source - if you want that too you'll have to make a third pass, with a similar find/script combination.