You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: manuscript/answers.md
+45-43Lines changed: 45 additions & 43 deletions
Original file line number
Diff line number
Diff line change
@@ -60,7 +60,7 @@ find /usr -name "*.txt"
60
60
61
61
The `/usr` path stores text files. So, there is no reason to check other system paths.
62
62
63
-
Now let's count the number of lines in the found files. We should add the `-exec` action with the `wc` utility call to do this. The resulting command looks like this:
63
+
Now let's count the number of lines in the found files. The `wc` utility can do this task. We should call the utility using the `-exec` action. Then the resulting command looks like this:
64
64
{line-numbers: false, format: Bash}
65
65
```
66
66
find /usr -name "*.txt" -exec wc -l {} +
@@ -78,95 +78,95 @@ If you add the `wc` call to the command, it fails when running in the MSYS2 envi
78
78
find / -name "*.txt" -exec wc -l {} +
79
79
```
80
80
81
-
The problem happens because of the error message that Figure 2-17 shows. The `find` utility passes the message to the `wc` input. The `wc` utility treats each word it receives as a file path. The error message is not a path. Therefore, `wc` fails.
81
+
The problem happens because of the error message that Figure 2-17 shows. The `find` utility passes its error message to the `wc` input. The `wc` utility treats each word it receives as a file path. The error message is not a path. Therefore, `wc` fails.
82
82
83
83
##### Exercise 2-4. Searching for files with the `grep` utility
84
84
85
85
Look for information about application licenses in the `/usr/share/doc` system path. It contains documentation for all installed software.
86
86
87
-
If the program has the [GNU General Public License](https://en.wikipedia.org/wiki/GNU_General_Public_License), its documentation contains the "General Public License" line. The following command searches such documents:
87
+
If the program has the [GNU General Public License](https://en.wikipedia.org/wiki/GNU_General_Public_License), its documentation contains the "General Public License" phrase. The following command searches this phrase in all documents:
88
88
{line-numbers: false, format: Bash}
89
89
```
90
90
grep -Rl "General Public License" /usr/share/doc
91
91
```
92
92
93
-
You also should check the files in the `/usr/share/licenses` path. Here is the command for doing that:
93
+
The `/usr/share/licenses` pathis the place where you can find license information for all installed software. You can search the "General Public License" phrase there with the following command:
94
94
{line-numbers: false, format: Bash}
95
95
```
96
96
grep -Rl "General Public License" /usr/share/licenses
97
97
```
98
98
99
-
The MSYS2 environment has two extra paths for installing programs: `/mingw32` and `/mingw64`. They do not match the POSIX standard. The following commands check documents in these paths:
99
+
The MSYS2 environment has two extra paths for installing programs: `/mingw32` and `/mingw64`. They do not match the POSIX standard. The following `grep` calls check these paths:
100
100
{line-numbers: true, format: Bash}
101
101
```
102
102
grep -Rl "General Public License" /mingw32/share/doc
103
103
grep -Rl "General Public License" /mingw64/share
104
104
```
105
105
106
-
You can find applications with other licenses than GNU General Public License. This is the list of licenses and possible lines for searching:
106
+
You can find applications with other licenses than GNU General Public License. Here is the list of licenses and corresponding phrases for searching:
107
107
108
108
* MIT - "MIT license"
109
109
* Apache - "Apache license"
110
110
* BSD - "BSD license"
111
111
112
112
##### Exercise 2-6. Operations with files and directories
113
113
114
-
First, you should create directories for saving photos by each year and month. The following commands do this task:
114
+
First, you should create directories for saving photos. Each directory should match a specific month of the year. The following commands create them:
115
115
{line-numbers: true, format: Bash}
116
116
```
117
117
mkdir -p ~/photo/2019/11
118
118
mkdir -p ~/photo/2019/12
119
119
mkdir -p ~/photo/2020/01
120
120
```
121
121
122
-
Suppose that the `D:\Photo` directory contains all photos. You can use the `find` utility for searching files with a creation date equals to November 2019. The `-newermt` option of the utility checks the creation date. Here is an example command:
122
+
Suppose that the `D:\Photo` directory contains all your photos. You can use the `find` utility to search photos created in November 2019. The `-newermt` option of the utility checks the creation date. Here is an example command of how to use it:
123
123
{line-numbers: false, format: Bash}
124
124
```
125
125
find /d/Photo -type f -newermt 2019-11-01 ! -newermt 2019-12-01
126
126
```
127
127
128
-
This command looks for files in the `/d/Photo` directory. It corresponds to the `D:\Photo` path in the Windows environment.
128
+
This command looks for files in the `/d/Photo` directory. It matches the `D:\Photo` path in the Windows environment.
129
129
130
-
The first expression `-newermt 2019-11-01`means to search for files changed since November 1, 2019. The second expression `! -newermt 2019-12-01` excludes files modified since December 1, 2019. The exclamation point before the expression is a negation. There is no condition between expressions. But the find utility inserts the logical AND by default. The resulting expression looks like: "files created after November 1, 2019, but no later than November 30, 2019". It means "files for November".
130
+
The first expression `-newermt 2019-11-01`points to files changed since November 1, 2019. The second expression `! -newermt 2019-12-01` excludes files modified since December 1, 2019. The exclamation point before the expression is a negation. There is no condition between expressions. The `find` utility inserts the logical AND by default. The resulting expression looks like: "files created after November 1, 2019, but no later than November 30, 2019". It means "the files created in November 2019".
131
131
132
-
The file search command is ready. Now add the copy action to it. The result looks like this:
132
+
The file search command is ready. Now we should add the copy action there. The result looks like this:
Let's assume that you do not need old files in the `D:\Photo` directory. Then replace copying action with renaming. The result is the following commands:
147
+
Let's assume that you do not need old files in the `D:\Photo` directory. Then you should replace the copying action with renaming. This way, you get the following commands:
Note the scalability of our solution. The number of files in the `D:\Photo` directory is not important. You need only three commands to break them up into three months.
155
+
Note the scalability of our solution. The number of files in the `D:\Photo` directory does not matter. You need only three commands to process them.
156
156
157
157
##### Exercise 2-7. Pipelines and I/O streams redirection
158
158
159
-
First, let's figure out how the `bsdtar` utility works. Call it with the `--help` option. It shows you a brief help. The help tells you that the utility archives the directory if you apply the `-c` and `-f` options. The name of the archive follows the options. Here is an example call of the `bsdtar` utility:
159
+
First, let's figure out how the `bsdtar` utility works. Call it with the `--help` option. It shows you a brief help. The help tells you that the utility archives a target directory if you apply the `-c` and `-f` options. You should specify the archive name after these options. Here is an example call of the `bsdtar` utility:
160
160
{line-numbers: false, format: Bash}
161
161
```
162
162
bsdtar -c -f test.tar test
163
163
```
164
164
165
-
This command creates an archive named `test.tar`. It has the contents of the `test` directory inside. Note that the command does not [compress data](https://en.wikipedia.org/wiki/Data_compression). It means that the archive occupies the same disk space as the files it contains.
165
+
This command creates the `test.tar` archive. It includes the contents of the `test` directory. Note that the command does not [compress data](https://en.wikipedia.org/wiki/Data_compression). It means that the archive occupies the same disk space as the files it contains.
166
166
167
-
The purposes of archiving and compression operations are different. Archiving is for storing and copying large numbers of files. Compression reduces the amount of the occupied disk memory. Often these operations are combined into one. But they are not the same.
167
+
The purposes of archiving and compression operations differ. You need archiving for storing and copying a large number of files. Compression reduces the amount of the occupied disk memory. These operations are combined into one often, but they are not the same.
168
168
169
-
To create an archive and compress it, add the `-j` option to the `bsdtar` call. Here is an example:
169
+
Suppose that you want to create an archive and compress it. Then you need to add the `-j` option to the `bsdtar` call. Here is an example:
170
170
{line-numbers: false, format: Bash}
171
171
```
172
172
bsdtar -c -j -f test.tar.bz2 test
@@ -178,37 +178,37 @@ You can combine the `-c`, `-j` and `-f` options into one group. Then you get the
178
178
bsdtar -cjf test.tar.bz2 test
179
179
```
180
180
181
-
Let's write a command to navigate through the catalog of photos. It should create a separate archive for each month.
181
+
Let's write a command for processing all photos. The command should archive each directory with the photos of the specific month.
182
182
183
-
The following `find` utility call finds directories that match specific months:
183
+
First, you need to find the directories for archiving. The following command does it:
184
184
{line-numbers: false, format: Bash}
185
185
```
186
186
find ~/photo -type d -path */2019/* -o -path */2020/*
187
187
```
188
188
189
-
Next, we redirect the output of this command to the `xargs` utility. It will generate the `bsdtar` call. Our command looks like this now:
189
+
Next, you redirect the output of the `find` call to the `xargs` utility. It will generate the `bsdtar` call. This way, you get the following command:
I> The data compression takes longer than archiving.
201
+
I> The data compression usually takes longer than archiving.
202
202
203
-
We pass the `-I` parameter to the `xargs` utility. It specifies where to insert the arguments into the generated command. There are two such places in the `bsdtar` utility call: the archive's name and the directory's path to be processed.
203
+
We pass the `-I` parameter to the `xargs` utility. It specifies the place to insert the arguments into the generated command. There are two such places in the `bsdtar` utility call: the archive's name and the directory's path to be processed.
204
204
205
-
Do not forget about filenames with line breaks. To process them correctly, add the `-print0` option to the `find`utility call. This way, we get the following command:
205
+
Do not forget about filenames with line breaks. To process them correctly, add the `-print0` option to the `find` call. This way, you get the following command:
Suppose that we want to keep the files in the archives without relative paths (e.g. `2019/11`). The `--strip-components` option of `bsdtar` removes them. Here is the command with this option:
211
+
Suppose that you want to keep the files in the archives without relative paths (e.g. `2019/11`). The `--strip-components` option of `bsdtar` removes them. The following command uses this option:
In this case, the `echo` command appends a line to the end of the existing log file.
243
+
Here the `echo` command appends the string to the end of the existing log file.
244
244
245
-
Let's combine the `cp` and `bsdtar`calls into one command. We should call the `bsdtar`utility only if the `README` file has been successfully copied. To achieve this dependency, we put the && operator between the commands. We get the following command:
245
+
Let's combine the `cp` and `bsdtar`utilities into one command. You should call `bsdtar` only if the `README` file has been copied successfully. To achieve this dependency, put the && operator between the calls. This way, you get the following command:
Run this command. If it succeeds, the log file looks like this:
257
+
Run this command in your terminal. If it succeeds, you get the following log file:
258
258
{line-numbers: true}
259
259
```
260
260
cp - OK
261
261
bsdtar - OK
262
262
rm - OK
263
263
```
264
264
265
-
The command with calls to three utilities in a rowlooks cumbersome. It is inconvenient to read and edit. Let's break the command into lines. There are several ways to do this.
265
+
The current version of our command calls three utilities in a row. It looks cumbersome and inconvenient for reading. Let's break the command into lines. There are several ways to do that.
266
266
267
-
The first way is to break lines after logical operators. We apply it and get the following:
267
+
The first way is to break lines after logical operators. If you apply this approach, you get the following result:
Try to copy this command into a terminal window and execute it. It will run without errors.
275
+
Copy this command to your terminal and execute it. It works properly.
276
276
277
-
The second way to add line breaks is to use the backslash character. Put a line break right after it. Use this method when there are no logical operators in the command.
277
+
The second way to add line breaks is to use the backslash symbol. Put a line break right after it. This method fits well when there are no logical operators in the command.
278
278
279
-
For example, let's put backslashes before the && operators in our command. Then we get this result:
279
+
For example, you can put backslashes before the && operators in our command. Then you get this result:
Run this command in your terminal. It works properly too.
288
+
287
289
## Bash Scrips
288
290
289
291
##### Exercise 3-2. The full form of parameter expansion
290
292
291
-
The `find` utility searches for files recursively. It starts from the specified path and passes through all subdirectories. Use the `-maxdepth` option to exclude subdirectories from the search.
293
+
The `find` utility searches for files recursively. It starts from the specified path and passes through all subdirectories. If you want to exclude subdirectories from the search, apply the `-maxdepth` option.
292
294
293
-
The command for searching TXT files in the current directory looks like this:
295
+
Here is the command for searching TXT files in the current directory:
294
296
{line-numbers: false, format: Bash}
295
297
```
296
298
find . -maxdepth 1 -type f -name "*.txt"
297
299
```
298
300
299
-
Let's add an action to copy the found files to the user's home directory. The command became like this:
301
+
Let's add an action to copy the found files to the user's home directory. The command becomes like this:
Now create a script and name it `txt-copy.sh`. Copy our `find` call into the file.
307
+
Now create a script and name it `txt-copy.sh`. Copy our `find` call to this file.
306
308
307
309
The script should receive an input parameter. The parameter defines an action to apply for each found file. There are two possible actions: copy or move. It is convenient to pass the utility's name as a parameter. Thus, it can be `cp` or `mv`. The script will call the utility by its name.
0 commit comments