4

My files are of the format

Country, City S1.txt

e.g.

USA, Los Angeles S1.txt
USA, San Francisco S3.txt
UK, Glouchester S4.txt
Argentina, Buenos Aires S7.txt

I wish to change them to

Country_City_S1.txt

e.g.

USA_Los_Angeles_S1.txt
USA_San_Franciso_S3.txt
UK_Glouchester_S4.txt
Argentina_Buenos_Aires_S7.txt

To remove the comma I use the following sed command:

sed -i 's/,//g'

To replace the whitespaces with underscore, I use the following sed command:

sed -i 's/ /_/g'

Question: Is there a way to combine the above two commands into one? Or is there a neater way to accomplish the above?

Notes:

  1. I have changed the title of my original post to better reflect what I need to be done. I am sorry for any confusion caused as a result of the change.

  2. I understand now what I need, which is a bash script and not sed to change filenames.

  3. I thank all those who have replied with their suggested sed commands.

  4. I prefer to use the mv command in a bash script as in for example *for f in .txt; do mv .......; done

Joel T.
  • 41
  • 3

4 Answers4

1

Replace any combination of spaces and commas with a single underscore:

sed -E 's/[, ]+/_/g'

See live demo.


To rename files using this regex on any *nix OS (macos doesn't ship with rename):

for f in *.txt; do mv $f $(echo "$f" | sed -E 's/[, ]+/_/g'); done

If your *nix has the rename command (brew install rename if you're macos):

rename 's/[, ]+/_/g' *.txt
Bohemian
  • 412,405
  • 93
  • 575
  • 722
0

Merge your two sed expressions:

sed 's/,//g; s/ /_/g'
Arnaud Valmary
  • 2,039
  • 9
  • 14
  • Bonjour Arnaud. I have made some changes to my original post, including the title of the subject. I am sorry for the confusion caused to you. – Joel T. Jul 06 '22 at 07:16
0

This might work for you (GNU sed):

sed 's/,//g;y/ /_/' file

Remove commas and translate spaces to underscores.

Or perhaps:

sed -E s/,? +/_/g' file

To rename file names, perhaps:

sed -E 'h;s/,? +//g;H;g;s/(.*)\n(.*)/mv "\1" "\2"/e' <<<"$filename"
potong
  • 55,640
  • 6
  • 51
  • 83
  • I have made a terrible mistake in my original post. sed commands don't work on changing of filenames, do they? Could you help with me a command that looks something like the following? for file in .......; do .......; done [Thank you in advance] – Joel T. Jul 06 '22 at 04:45
  • @JoelT changing filenames is best done using `rename` or `mv` . The `rename` command uses perl see [here](https://stackoverflow.com/questions/11809666/rename-files-using-regular-expression-in-linux). – potong Jul 06 '22 at 06:56
  • I don't wish to use `rename`. In fact I was thinking of using `mv` as in `for f in *.txt; do mv .......; done` Can you help me please? Thanks in advance. – Joel T. Jul 06 '22 at 07:03
  • I tried your tip on renaming filenames using `sed`. The error message is: *sed: -e expression #1, char 18: unknown option to `s'* – Joel T. Jul 06 '22 at 09:58
  • Per your advice, I first removed the `e` flag and ran your `sed` command again. I have the same error message. – Joel T. Jul 06 '22 at 16:52
  • I tried your solution again and the same error message appeared. – Joel T. Jul 07 '22 at 11:53
  • @JoelT. Hmm? See [here](https://www.ideone.com/WdC7My) – potong Jul 07 '22 at 12:39
0

One line solution here:

find *.txt | sed -E 'p;s/[, ]+/_/g' | tr '\n' '\0' | xargs -0 -n2 mv

This is a very useful command template for batch renaming files:

find ... | sed 'p;s/...' | tr '\n' '\0' | xargs -0 -n2 mv
arzyu
  • 13
  • 6