How to remove a file name prefix using the Posix shell

How to remove the file name prefix in Bash, as in the following example:

XY TD-11212239.pdf 

To obtain

 11212239.pdf 

ie, delete XY TD- ?

+22
bash shell prefix
May 10 '12 at 14:18
source share
5 answers

You have provided very little information, but assuming that you are doing this in bash and have a list of files whose prefix needs to be removed, you can pass the list through sed :

For example:

 ./generate_your_list_of_files | sed -e 's/^prefix//' 

or if your file list is separated by spaces:

 echo TD-file1 TD-file2.x.yt TD-file3-beep | sed -e 's/\<TD-//g' 

The first matches the prefix at the beginning of the line and removes it. The second corresponds to TD- (or any other prefix that you want to replace) only when it occurs at the beginning of a word and replaces it in all matches on all lines. This can become dangerous, for example, for example, the file TD-file\ that\ TD-contains\ space.txt becomes file\ that\ contains\ space.txt

As an extra note, don't get a list of files with ls . This is a terrible mistake . If you need to get a list of files to work and links in more than one place, I would suggest putting them in an array:

 files=(*) 

and then work with this array.




Due to popular queries (one comment below), here's how to rename all files in a directory starting with XY TD- so that the prefix is ​​removed (thanks @tripleee):

 for file in prefix*; do mv "$file" "${file#XY TD-}" done 
+26
May 10 '12 at 2:26 p.m.
source share

You said POSIX shells will include BASH, Kornshell, Ash, Zsh, and Dash. Fortunately, all of these shells have filtering patterns by variable values.

Templates are what you use when you specify files with things like * on the Unix / Linux command line:

 $ ls *.sh # Lists all files with a `.sh` suffix 

These POSIX shells use four different filters:

  • ${var#pattern} - Deletes the smallest line on the left side that matches the pattern.
  • ${var##pattern} - Deletes a large line on the left side that matches the pattern.
  • ${var%pattern} - Deletes the smallest line on the right side that matches the pattern.
  • ${var%%pattern} - Deletes the largest line on the right side that matches the pattern.

Here are some examples:

 foo="foo-bar-foobar" echo ${foo#*-} # echoes 'bar-foobar' (Removes 'foo-' because that matches '*-') echo ${foo##*-} # echoes 'foobar' (Removes 'foo-bar-') echo ${foo%-*} # echoes 'foo-bar' echo ${foo%%-*} # echoes 'foo' 

You really haven’t explained what you want, and you haven’t provided any sample code, so it’s hard to come up with something that will do what you want. However, using template filtering, you can probably determine exactly what you want to do with the file names.

 file_name="XY TD-11212239.pdf" mv "$file_name" "${file_name#*-}" # Removes everything from up to the first dash 
+20
Aug 27 '14 at 21:05
source share

You can also use the rename tool

Install it with a homegrown

brew install rename

Then run the following command from the directory to remove the “prefix-” from all files

rename -d prefix- *

+3
Aug 27 '14 at 19:54
source share

In addition to the substring extraction shown in other answers, you can also use substring replacement. Given the file:

 fn="XY TD-11212239.pdf" 

Then substring substring:

 fn_new=${fn//*TD-/} 

Will do what you want.

+2
Aug 27 '14 at 20:50
source share
 $ s='XY TD-11212239.pdf' $ echo "${s#XY TD-}" 11212239.pdf 

If you want to perform bulk renaming:

 while IFS= read -r -d '' filename; do mv "$filename" "${filename#XY TD-}" done < <(find . -type f -name 'XY TD-*' -print0) 

Note that <() is a bash extension that is not present in POSIX sh. You can replace it with the find ... | while form pipeline find ... | while find ... | while .

Similarly, -print0 is a GNU extension that is not found in POSIX search. POSIX search does not provide an equivalent way to search for files that are safe for names containing newlines, making it difficult to replace them.

+1
Aug 27 '14 at 19:58
source share



All Articles