Skip to content

Commit c77b3ad

Browse files
committedOct 4, 2021
edited the remaining chapters
1 parent 3c1013c commit c77b3ad

9 files changed

+43
-25
lines changed
 

‎basename-dirname.html

+5-3
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
$ basename 'path with spaces/report.log'
4646
report.log
4747

48-
# trailing slashes will not affect the output
48+
# one or more trailing slashes will not affect the output
4949
$ basename /home/learnbyexample/example_files/
5050
example_files
5151
</code></pre><p>If there's no leading directory component or if slash alone is the input, the argument will be returned as is after removing any trailing slashes.<pre><code class=language-bash>$ basename filename.txt
@@ -65,13 +65,15 @@
6565
$ basename -s'.txt' purchases.txt.txt
6666
purchases.txt
6767

68-
$ basename -s'report' report
68+
# -s will be ignored if it would have resulted in empty output
69+
$ basename -s'report' /backups/report
6970
report
7071
</code></pre><p>You can also pass the suffix to be removed after the path argument, but the <code>-s</code> option is preferred as it makes the intention clearer and works for multiple path arguments.<pre><code class=language-bash>$ basename example_files/scores.csv .csv
7172
scores
7273
</code></pre><h2 id=remove-filename-from-path><a class=header href=#remove-filename-from-path>Remove filename from path</a></h2><p>By default, the <code>dirname</code> command removes the trailing path component (after removing any trailing slashes).<pre><code class=language-bash>$ dirname /home/learnbyexample/example_files/scores.csv
7374
/home/learnbyexample/example_files
7475

76+
# one or more trailing slashes will not affect the output
7577
$ dirname /home/learnbyexample/example_files/
7678
/home/learnbyexample
7779
</code></pre><h2 id=multiple-arguments><a class=header href=#multiple-arguments>Multiple arguments</a></h2><p>The <code>dirname</code> command accepts multiple path arguments by default. The <code>basename</code> command requires <code>-a</code> or <code>-s</code> (which implies <code>-a</code>) to work with multiple arguments.<pre><code class=language-bash>$ basename -a /backups/jan_2021.tar.gz /home/learnbyexample/report.log
@@ -86,7 +88,7 @@
8688
$ dirname /home/learnbyexample/example_files/scores.csv ../report/backups/
8789
/home/learnbyexample/example_files
8890
../report
89-
</code></pre><h2 id=combining-basename-and-dirname><a class=header href=#combining-basename-and-dirname>Combining basename and dirname</a></h2><p>You can use shell features like command substitution to combine the effects of <code>basename</code> and <code>dirname</code> commands.<pre><code class=language-bash># extract the second last component
91+
</code></pre><h2 id=combining-basename-and-dirname><a class=header href=#combining-basename-and-dirname>Combining basename and dirname</a></h2><p>You can use shell features like command substitution to combine the effects of <code>basename</code> and <code>dirname</code> commands.<pre><code class=language-bash># extract the second last path component
9092
$ basename $(dirname /home/learnbyexample/example_files/scores.csv)
9193
example_files
9294
</code></pre><h2 id=nul-separator><a class=header href=#nul-separator>NUL separator</a></h2><p>Use <code>-z</code> option if you want to use NUL character as the output path separator.<pre><code class=language-bash>

‎csplit.html

+4-4
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@
6161
10
6262

6363
$ rm xx*
64-
</code></pre><blockquote><p><img src=./images/info.svg alt=info> As seen in the example above, <code>csplit</code> will also display the number of bytes written for each output file. You can use the <code>-q</code> option to suppress this message.</blockquote><blockquote><p><img src=./images/info.svg alt=info> <img src=./images/warning.svg alt=warning> As mentioned earlier, remove the output files after every illustration.</blockquote><h2 id=split-on-regexp><a class=header href=#split-on-regexp>Split on regexp</a></h2><p>You can also split the input based on a line matching the given regular expression. The output produced will vary based on <code>//</code> or <code>%%</code> being used to surround the regexp.<p>When <code>/regexp/</code> is used, output is similar to the line number based splitting. The first output file will have the input lines <em>before</em> the first occurrence of a line matching the given regexp and the second output file will have the rest of the contents.<pre><code class=language-bash># match a line containing 't' followed by zero or more characters and then 'p'
65-
# 'toothpaste' matches for this input file
64+
</code></pre><blockquote><p><img src=./images/info.svg alt=info> As seen in the example above, <code>csplit</code> will also display the number of bytes written for each output file. You can use the <code>-q</code> option to suppress this message.</blockquote><blockquote><p><img src=./images/info.svg alt=info> <img src=./images/warning.svg alt=warning> As mentioned earlier, remove the output files after every illustration.</blockquote><h2 id=split-on-regexp><a class=header href=#split-on-regexp>Split on regexp</a></h2><p>You can also split the input based on a line matching the given regular expression. The output produced will vary based on <code>//</code> or <code>%%</code> delimiters being used to surround the regexp.<p>When <code>/regexp/</code> is used, output is similar to the line number based splitting. The first output file will have the input lines <em>before</em> the first occurrence of a line matching the given regexp and the second output file will have the rest of the contents.<pre><code class=language-bash># match a line containing 't' followed by zero or more characters and then 'p'
65+
# 'toothpaste' is the only match for this input file
6666
$ csplit -q purchases.txt '/t.*p/'
6767

6868
$ head xx*
@@ -127,8 +127,8 @@
127127

128128
$ csplit -q purchases.txt '/t.*p/-5'
129129
csplit: ‘/t.*p/-5’: line number out of range
130-
</code></pre><h2 id=repeat-split><a class=header href=#repeat-split>Repeat split</a></h2><p>You can perform line number and regexp based split more than once by adding <code>{N}</code> argument after the pattern. Default behavior is same as specifying <code>{0}</code>. Any number greater than zero will result in that many more splits.<pre><code class=language-bash># {1} means split one more time
131-
# so two splits in total and three output files
130+
</code></pre><h2 id=repeat-split><a class=header href=#repeat-split>Repeat split</a></h2><p>You can perform line number and regexp based split more than once by adding <code>{N}</code> argument after the pattern. Default behavior examples seen so far is same as specifying <code>{0}</code>. Any number greater than zero will result in that many more splits.<pre><code class=language-bash># {1} means split one time more than the default split
131+
# so, two splits in total and three output files
132132
# in this example, split happens on 4th and 8th line numbers
133133
$ seq 10 | csplit -q - 4 '{1}'
134134

‎expand-unexpand.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
# 'αλε' = 6 bytes, \t converts to 2 spaces
5353
$ printf 'αλε\tπού\n' | expand
5454
αλε πού
55-
</code></pre><p>Here's an example with <code>7</code> and <code>8</code> byte strings before the tab character:<pre><code class=language-bash>$ printf 'deviate\treached\nbackdrop\toverhang\n' | expand
55+
</code></pre><p>Here's an example with strings of size <code>7</code> and <code>8</code> bytes before the tab character:<pre><code class=language-bash>$ printf 'deviate\treached\nbackdrop\toverhang\n' | expand
5656
deviate reached
5757
backdrop overhang
5858
</code></pre><p>The <code>expand</code> command also considers backspace characters to determine the number of spaces needed.<pre><code class=language-bash># sample input with a backspace character
@@ -140,7 +140,7 @@
140140
^I^Ia b c
141141

142142
# input has 4 spaces and a tab character (that expands till 8th column)
143-
# output will have only the tab character at the start
143+
# output will have a single tab character at the start
144144
$ printf ' \ta b\n' | unexpand | cat -T
145145
^Ia b
146146
</code></pre><blockquote><p><img src=./images/info.svg alt=info> The current <code>locale</code> determines which characters are considered as blanks. Also, <code>unexpand</code> will concatenate multiple files passed as input source, so <code>cat</code> will not be needed for such cases.</blockquote><h2 id=unexpand-all-blanks><a class=header href=#unexpand-all-blanks>Unexpand all blanks</a></h2><p>The <code>-a</code> option will allow you to convert all sequences of two or more blanks at tab boundaries. Here's some examples:<pre><code class=language-bash># default unexpand stops at first non-blank character

‎join.html

+12-4
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@
134134
Raj,ECE,53
135135
Raj,EEE,88
136136
Tia,EEE,72
137-
</code></pre><h2 id=customize-output-field-list><a class=header href=#customize-output-field-list>Customize output field list</a></h2><p>You can use the <code>-o</code> option to customize the fields required in the output and their order. Especially useful when the first field isn't the key. Each output field is specified as file number, followed by a <code>.</code> character and then the field number. You can specify multiple fields separated by a <code>,</code> character. As a special case, you can use <code>0</code> to indicate the key field.<pre><code class=language-bash># output field order is 1st, 2nd and 3rd fields from the first file
137+
</code></pre><h2 id=customize-output-field-list><a class=header href=#customize-output-field-list>Customize output field list</a></h2><p>You can use the <code>-o</code> option to customize the fields required in the output and their order. Especially useful when the first field isn't the key. Each output field is specified as file number followed by a <code>.</code> character and then the field number. You can specify multiple fields separated by a <code>,</code> character. As a special case, you can use <code>0</code> to indicate the key field.<pre><code class=language-bash># output field order is 1st, 2nd and 3rd fields from the first file
138138
$ join -t, -1 2 -o 1.1,1.2,1.3 <(sort -t, -k2,2 marks.csv) names.txt
139139
CSE,Amy,67
140140
ECE,Raj,53
@@ -174,7 +174,15 @@
174174
pen NA 2
175175
soap 3 1
176176
tshirt 3 NA
177-
</code></pre><h2 id=set-operations><a class=header href=#set-operations>Set operations</a></h2><p>This section covers whole line set operations you can perform on already sorted input files. Equivalent <code>sort</code> and <code>uniq</code> (if required) solutions will also be mentioned as comments (useful for unsorted inputs). Assume that there are no duplicate lines within an input file.<pre><code class=language-bash># union
177+
</code></pre><h2 id=set-operations><a class=header href=#set-operations>Set operations</a></h2><p>This section covers whole line set operations you can perform on already sorted input files. Equivalent <code>sort</code> and <code>uniq</code> solutions will also be mentioned as comments (useful for unsorted inputs). Assume that there are no duplicate lines within an input file.<p>These two sorted input files will be used for the examples to follow:<pre><code class=language-bash>$ paste colors_1.txt colors_2.txt
178+
Blue Black
179+
Brown Blue
180+
Orange Green
181+
Purple Orange
182+
Red Pink
183+
Teal Red
184+
White White
185+
</code></pre><p>Here's how you can get <em>union</em> and <em>symmetric difference</em> results. Recall that <code>-t ''</code> will cause entire input line content to be considered as keys.<pre><code class=language-bash># union
178186
# unsorted input: sort -u colors_1.txt colors_2.txt
179187
$ join -t '' -a1 -a2 colors_1.txt colors_2.txt
180188
Black
@@ -197,7 +205,7 @@
197205
Pink
198206
Purple
199207
Teal
200-
</code></pre><p>The below examples also include the equivalent <code>comm</code> solutions.<pre><code class=language-bash># intersection, same as: comm -12 colors_1.txt colors_2.txt
208+
</code></pre><p>Here's how you can get <em>intersection</em> and <em>difference</em> results. The equivalent <code>comm</code> solutions for sorted input is also mentioned in the comments.<pre><code class=language-bash># intersection, same as: comm -12 colors_1.txt colors_2.txt
201209
# unsorted input: sort colors_1.txt colors_2.txt | uniq -d
202210
$ join -t '' colors_1.txt colors_2.txt
203211
Blue
@@ -218,7 +226,7 @@
218226
Brown
219227
Purple
220228
Teal
221-
</code></pre><p>As mentioned before, <code>join</code> will display all the combinations if there are duplicate entries. Here's an example for displaying common lines:<pre><code class=language-bash>$ paste list_1.txt list_2.txt
229+
</code></pre><p>As mentioned before, <code>join</code> will display all the combinations if there are duplicate entries. Here's an example to show the differences between <code>sort</code>, <code>comm</code> and <code>join</code> solutions for displaying common lines:<pre><code class=language-bash>$ paste list_1.txt list_2.txt
222230
apple cherry
223231
banana cherry
224232
cherry mango

‎nl.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
7 42
5050
8 1000
5151

52-
# input with empty lines, same as: cat -b
52+
# example for input with empty lines, same as: cat -b
5353
$ printf 'apple\n\nbanana\n\ncherry\n' | nl
5454
1 apple
5555

@@ -252,6 +252,6 @@
252252
5 tea
253253
soap
254254
6 tea
255-
</code></pre><blockquote><p><img src=./images/info.svg alt=info> See <a href=https://learnbyexample.github.io/learn_gnugrep_ripgrep/breere-regular-expressions.html>Regular Expressions</a> chapter from my <strong>GNU grep</strong> ebook if you want to learn about BRE syntax and features.</blockquote></main><nav class=nav-wrapper aria-label="Page navigation"><a rel=prev href=join.html class="mobile-nav-chapters previous"title="Previous chapter"aria-label="Previous chapter"aria-keyshortcuts=Left> <i class="fa fa-angle-left"></i> </a><a rel=next href=wc.html class="mobile-nav-chapters next"title="Next chapter"aria-label="Next chapter"aria-keyshortcuts=Right> <i class="fa fa-angle-right"></i> </a><div style="clear: both"></div></nav></div></div><nav class=nav-wide-wrapper aria-label="Page navigation"><a rel=prev href=join.html class="nav-chapters previous"title="Previous chapter"aria-label="Previous chapter"aria-keyshortcuts=Left> <i class="fa fa-angle-left"></i> </a><a rel=next href=wc.html class="nav-chapters next"title="Next chapter"aria-label="Next chapter"aria-keyshortcuts=Right> <i class="fa fa-angle-right"></i> </a></nav></div><script>
255+
</code></pre><blockquote><p><img src=./images/info.svg alt=info> See <a href=https://learnbyexample.github.io/learn_gnugrep_ripgrep/breere-regular-expressions.html>Regular Expressions</a> chapter from my <strong>GNU grep</strong> ebook if you want to learn about regexp syntax and features.</blockquote></main><nav class=nav-wrapper aria-label="Page navigation"><a rel=prev href=join.html class="mobile-nav-chapters previous"title="Previous chapter"aria-label="Previous chapter"aria-keyshortcuts=Left> <i class="fa fa-angle-left"></i> </a><a rel=next href=wc.html class="mobile-nav-chapters next"title="Next chapter"aria-label="Next chapter"aria-keyshortcuts=Right> <i class="fa fa-angle-right"></i> </a><div style="clear: both"></div></nav></div></div><nav class=nav-wide-wrapper aria-label="Page navigation"><a rel=prev href=join.html class="nav-chapters previous"title="Previous chapter"aria-label="Previous chapter"aria-keyshortcuts=Left> <i class="fa fa-angle-left"></i> </a><a rel=next href=wc.html class="nav-chapters next"title="Next chapter"aria-label="Next chapter"aria-keyshortcuts=Right> <i class="fa fa-angle-right"></i> </a></nav></div><script>
256256
window.playground_copyable = true;
257257
</script><script src=elasticlunr.min.js charset=utf-8></script><script src=mark.min.js charset=utf-8></script><script src=searcher.js charset=utf-8></script><script src=clipboard.min.js charset=utf-8></script><script src=highlight.js charset=utf-8></script><script src=book.js charset=utf-8></script><script src=sidebar.js></script>

‎searchindex.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎searchindex.json

+1-1
Large diffs are not rendered by default.

‎split.html

+6-3
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
3939
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
4040
});
41-
</script><div id=content class=content><main><div class=sidetoc><nav class=pagetoc></nav></div><h1 id=split><a class=header href=#split>split</a></h1><p>The <code>split</code> command is useful to divide the input into smaller parts based on number of lines, bytes, file size, etc. You can also execute another command on the divided parts before saving the results. An example use case is sending a large file as multiple parts to workaround online transfer size limits.<blockquote><p><img src=./images/info.svg alt=info> Since a lot of output files will be generated in this chapter (often with same filenames), remove these files after every illustration.</blockquote><h2 id=default-split><a class=header href=#default-split>Default split</a></h2><p>By default, the <code>split</code> command divides the input <code>1000</code> lines at a time. Newline character is the default line separator. You can pass a single file or <code>stdin</code> data as the input. Use <code>cat</code> if you need to concatenate multiple input sources.<p>By default, the output files will be named <code>xaa</code>, <code>xab</code>, <code>xac</code> and so on (where <code>x</code> is the prefix). If the filenames are exhausted, two more letters will be appended and the pattern will continue as needed. If the number of input lines is not evenly divisible, the last file will contain less than <code>1000</code> lines.<pre><code class=language-bash># divide input 1000 lines at a time
41+
</script><div id=content class=content><main><div class=sidetoc><nav class=pagetoc></nav></div><h1 id=split><a class=header href=#split>split</a></h1><p>The <code>split</code> command is useful to divide the input into smaller parts based on number of lines, bytes, file size, etc. You can also execute another command on the divided parts before saving the results. An example use case is sending a large file as multiple parts as a workaround for online transfer size limits.<blockquote><p><img src=./images/info.svg alt=info> Since a lot of output files will be generated in this chapter (often with same filenames), remove these files after every illustration.</blockquote><h2 id=default-split><a class=header href=#default-split>Default split</a></h2><p>By default, the <code>split</code> command divides the input <code>1000</code> lines at a time. Newline character is the default line separator. You can pass a single file or <code>stdin</code> data as the input. Use <code>cat</code> if you need to concatenate multiple input sources.<p>By default, the output files will be named <code>xaa</code>, <code>xab</code>, <code>xac</code> and so on (where <code>x</code> is the prefix). If the filenames are exhausted, two more letters will be appended and the pattern will continue as needed. If the number of input lines is not evenly divisible, the last file will contain less than <code>1000</code> lines.<pre><code class=language-bash># divide input 1000 lines at a time
4242
$ seq 10000 | split
4343

4444
# output filenames
@@ -155,14 +155,14 @@
155155
8 10 57 total
156156
</code></pre><blockquote><p><img src=./images/warning.svg alt=warning> Since the division is based on file size, <code>stdin</code> data cannot be used.</blockquote><pre><code class=language-bash>$ seq 6 | split -n2
157157
split: -: cannot determine file size
158-
</code></pre><p>By using <code>K/N</code> as the argument, you can view the <code>K</code>th chunk of <code>N</code> parts on <code>stdout</code>. No output file will be created in this scenario.<pre><code class=language-bash># divided the input into 2 parts
158+
</code></pre><p>By using <code>K/N</code> as the argument, you can view the <code>K</code>th chunk of <code>N</code> parts on <code>stdout</code>. No output file will be created in this scenario.<pre><code class=language-bash># divide the input into 2 parts
159159
# view only the 1st chunk on stdout
160160
$ split -n1/2 greeting.txt
161161
Hi there
162162
Hav
163163
</code></pre><p>To avoid splitting a line, use <code>l/</code> as a prefix. Quoting from the <a href=https://www.gnu.org/software/coreutils/manual/html_node/split-invocation.html>manual</a>:<blockquote><p>For <code>l</code> mode, chunks are approximately <code>input size / N</code>. The input is partitioned into <code>N</code> equal sized portions, with the last assigned any excess. If a line starts within a partition it is written completely to the corresponding file. Since lines or records are not split even if they overlap a partition, the files written can be larger or smaller than the partition size, and even empty if a line/record is so long as to completely overlap the partition.</blockquote><pre><code class=language-bash># divide input into 2 parts, don't split lines
164-
165164
$ split -nl/2 purchases.txt
165+
166166
$ head x*
167167
==> xaa <==
168168
coffee
@@ -231,6 +231,9 @@
231231

232232
$ seq 100 | split -l1 -a1
233233
split: output file suffixes exhausted
234+
$ ls x*
235+
xa xc xe xg xi xk xm xo xq xs xu xw xy
236+
xb xd xf xh xj xl xn xp xr xt xv xx xz
234237
</code></pre><p>You can use the <code>-d</code> option to use numeric suffixes, starting from <code>00</code> (length depends on the <code>-a</code> setting). You can use the long option <code>--numeric-suffixes</code> to specify a different starting number.<pre><code class=language-bash>$ seq 10 | split -l1 -d
235238
$ ls x*
236239
x00 x01 x02 x03 x04 x05 x06 x07 x08 x09

‎wc.html

+10-5
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444

4545
$ wc greeting.txt
4646
2 6 25 greeting.txt
47-
</code></pre><p>If you are wondering why there are leading spaces, they help in aligning results for multiple files (discussed later).<h2 id=individual-counts><a class=header href=#individual-counts>Individual counts</a></h2><p>Instead of the three default values, you can use options to get only the particular count(s) you are interested in. These options are:<ul><li><code>-l</code> for line count<li><code>-w</code> for word count<li><code>-c</code> for byte count</ul><pre><code class=language-bash>$ wc -l greeting.txt
47+
</code></pre><p>Wondering why there are leading spaces in the output? They help in aligning results for multiple files (discussed later).<h2 id=individual-counts><a class=header href=#individual-counts>Individual counts</a></h2><p>Instead of the three default values, you can use options to get only the particular count(s) you are interested in. These options are:<ul><li><code>-l</code> for line count<li><code>-w</code> for word count<li><code>-c</code> for byte count</ul><pre><code class=language-bash>$ wc -l greeting.txt
4848
2 greeting.txt
4949

5050
$ wc -w greeting.txt
@@ -60,17 +60,18 @@
6060
$ printf 'hello' | wc -c -
6161
5 -
6262

63-
$ wc -l &LTgreeting.txt
63+
$ lines=$(wc -l &LTgreeting.txt)
64+
$ echo "$lines"
6465
2
65-
</code></pre><h2 id=multiple-files><a class=header href=#multiple-files>Multiple files</a></h2><p>If you pass multiple files to the <code>wc</code> command, the count values will be displayed separately for each file. You'll also get a summary at the end, which is the sum of all the input files.<pre><code class=language-bash>$ wc greeting.txt nums.txt purchases.txt
66+
</code></pre><h2 id=multiple-files><a class=header href=#multiple-files>Multiple files</a></h2><p>If you pass multiple files to the <code>wc</code> command, the count values will be displayed separately for each file. You'll also get a summary at the end, which sums the respective count of all the input files.<pre><code class=language-bash>$ wc greeting.txt nums.txt purchases.txt
6667
2 6 25 greeting.txt
6768
3 3 13 nums.txt
6869
8 9 57 purchases.txt
6970
13 18 95 total
7071
$ wc greeting.txt nums.txt purchases.txt | tail -n1
7172
13 18 95 total
7273

73-
$ wc *.csv
74+
$ wc *[ck]*.csv
7475
9 9 101 marks.csv
7576
4 4 70 scores.csv
7677
13 13 171 total
@@ -122,16 +123,20 @@
122123
# allow numbers as well
123124
$ echo '2 : apples ;' | tr -cd '[:alnum:][:space:]' | wc -w
124125
2
125-
</code></pre><p><code>-L</code> won't count non-printable characters and tabs are converted to equivalent spaces. Multibyte characters will each be counted as <code>1</code> (depending on the locale, they might become non-printable too).<pre><code class=language-bash>$ printf '\t' | wc -L
126+
</code></pre><p><code>-L</code> won't count non-printable characters and tabs are converted to equivalent spaces. Multibyte characters will each be counted as <code>1</code> (depending on the locale, they might become non-printable too).<pre><code class=language-bash># tab characters can occupy up to 8 columns
127+
$ printf '\t' | wc -L
126128
8
127129
$ printf 'a\tb' | wc -L
128130
9
129131

132+
# example for non-printable character
130133
$ printf 'a\34b' | wc -L
131134
2
132135

136+
# multibyte characters are counted as 1 each in supported locales
133137
$ printf 'αλεπού' | wc -L
134138
6
139+
# non-supported locales can cause them to be treated as non-printable
135140
$ printf 'αλεπού' | LC_ALL=C wc -L
136141
0
137142
</code></pre><p><code>-m</code> and <code>-L</code> options count <a href=https://unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries>grapheme clusters</a> differently.<pre><code class=language-bash>$ printf 'cag̈e' | wc -m

0 commit comments

Comments
 (0)
Please sign in to comment.