How can I manipulate file names using bash and sed?

I am trying to iterate over all the files in a directory.

I want to do some things in each file (convert it to xml, not included in the example), and then write the file to a new directory structure.

for file in `find /home/devel/stuff/static/ -iname "*.pdf"`; do echo $file; sed -e 's/static/changethis/' $file > newfile +".xml"; echo $newfile; done 

I want the results to be:

$ file => /home/devel/stuff/static/2002/hello.txt

$ newfile => /home/devel/stuff/changethis/2002/hello.txt.xml

How do I change my sed string?

+4
source share
6 answers

If you need to rename multiple files, I would suggest using the rename command:

 # remove "-n" after you verify it is what you need rename -n 's/hello/hi/g' $(find /home/devel/stuff/static/ -type f) 

or, if you do not have rename , try the following:

 find /home/devel/stuff/static/ -type f | while read FILE do # modify line below to do what you need, then remove leading "echo" echo mv $FILE $(echo $FILE | sed 's/hello/hi/g') done 
+5
source

Are you trying to change the file name? Then

 for file in /home/devel/stuff/static/*/*.txt do echo "Moving $file" mv "$file" "${file/static/changethis}.xml" done 

Please make sure that /home/devel/stuff/static/*/*.txt is what you want before using the script.

+2
source

You must first create a new file name based on the name of the original file. The obvious solution:

 newfile=${file/static/changethis}.xml 

Secondly, you must make sure that a new directory exists or create it if not:

 mkdir -p $(dirname $newfile) 

Then you can do something with your file:

 doSomething < $file > $newfile 
+1
source

I would not do a for loop because of the ability to overload your command line. Command lines have a limited length, and if you overload it, it will simply turn off the excess without giving you any warnings. It can work if your search returns 100 files. It may work if it returns 1000 files, but may be unsuccessful if your search returns 1000 files and you will never know.

The best way to handle this is to direct the search into the read expression as glenn jackman .

The sed command only works with STDIN and files, but not with file names, so if you want to change the file name, you need to do something like this:

 $newname="$(echo $oldname | sed 's/old/new/')" 

to get the new file name. The $() construct executes the command and puts the results of the command in STDOUT.

So your script will look something like this:

 find /home/devel/stuff/static/ -name "*.pdf" | while read $file do echo $file; newfile="$(echo $file | sed -e 's/static/changethis/')" newfile="$newfile.xml" echo $newfile; done 

Now, since you are renaming the file directory, you need to make sure that the directory exists before you move or copy:

 find /home/devel/stuff/static/ -name "*.pdf" | while read $file do echo $file; newfile="$(echo $file | sed -e 's/static/changethis/')" newfile="$newfile.xml" echo $newfile; #Check for directory and create it if it doesn't exist $dirname=$(dirname "$newfile") if [ ! -d "$dirname" ] then mkdir -p "$dirname" fi #Directory now exists, so you can do the move mv "$file" "$newfile" done 

Pay attention to the quotation marks to handle in this case a space in the file name.

By the way, instead:

 if [ ! -d "$dirname" ] then mkdir -p "$dirname" fi 

You can do it:

 [ -d "$dirname"] || mkdir -p "$dirname" 

|| means the following command is executed only if the test is invalid. Thus, if [-d "$ dirname"] is a false statement (the directory does not exist), you run mkdir .

This is a fairly common shortcut when viewing shell scripts.

+1
source
 find ... | while read file; do newfile=$(basename "$file").xml; do something to "$file" > "$somedir/$newfile" done 
0
source
 OUTPUT="$(pwd)"; for file in `find . -iname "*.pdf"`; do echo $file; cp $file $file.xml echo "file created in directory = {$OUTPUT}" done 

This will create a new file called whatyourfilename.xml, for hello.pdf the new file created will be hello.pdf.xml, basically it will create a new file with the .xml added at the end.

Remember that the script mentioned above finds the files in the directory /home/devel/stuff/static/ , whose file names correspond to the match string of the find command (in this case * .pdf) and copies it to your current working directory.

The find command in this particular script only finds files with file names ending in .pdf. If you want to run this script for files with file names ending in .txt, then you need to change the find command to find /home/devel/stuff/static/ -iname "*.txt" ,

0
source

Source: https://habr.com/ru/post/1369648/


All Articles