The Computer Oracle

Properly escaping forward slash in bash script for usage with sed

--------------------------------------------------
Rise to the top 3% as a developer or hire one of them at Toptal: https://topt.al/25cXVn
--------------------------------------------------

Music by Eric Matyas
https://www.soundimage.org
Track title: Magical Minnie Puzzles

--

Chapters
00:00 Properly Escaping Forward Slash In Bash Script For Usage With Sed
00:56 Accepted Answer Score 34
01:19 Answer 2 Score 0
02:31 Thank you

--

Full question
https://superuser.com/questions/766595/p...

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#linux #bash #rsync #sed #bashscripting

#avk47



ACCEPTED ANSWER

Score 34


You don't actually need to bother with escaping the /. From the GNU sed manual:

The / characters may be uniformly replaced by any other single character within any given s command.

For example:

echo 'foobar' | sed -e 's#foo#bar#'

gives the output

barbar



ANSWER 2

Score 0


If you are trying to tally up the data, you will likely want to skip over any possible subdirectories. This may not be applicable, but it's always best to avoid any weirdness. Here is my source directory. These files were all created with touch, so they take up 0 space.

$ find source
source
source/5832
source/5832/5832_1.png
source/5832/5832_2.png
source/5831
source/5831/5831_1.png
source/5830
source/5830/5830_3.png
source/5830/5830_1.png
source/5830/5830_2.png

You shouldn't need to escape anywhere near as much as you are doing. The sed block in here will do the following:
1d; delete the first line of 'sending incremental file list'
/^$/,$d; delete the blank line that signifies end of file list and everything after it.
//$/d delete any line ending in a '/', which would be the directories
Note that you can escape the slashes with backslashes (to answer the actual question).

$ du $(rsync -ahnv source target | sed '1d;/^$/,$d;/\/$/d')
0   source/5830/5830_1.png
0   source/5830/5830_2.png
0   source/5830/5830_3.png
0   source/5831/5831_1.png
0   source/5832/5832_1.png
0   source/5832/5832_2.png

And for extra bonus points, you can even tally up the results:

$ du -s $(rsync -ahnv source target | sed '1d;/^$/,$d;/\/$/d') | awk '{x+=$1;print $0} END {print "sum: "x}'
0   source/5830/5830_1.png
0   source/5830/5830_2.png
0   source/5830/5830_3.png
0   source/5831/5831_1.png
0   source/5832/5832_1.png
0   source/5832/5832_2.png
sum: 0

If you are doing this with the directory already fully synced, it will return funny results, though:

76  .
sum: 76