srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/data/packs/shell.json
blob: b7f83124597db010f9b144a22e816754240c0169 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
[
  {
    "category": "shell",
    "language": "shell",
    "attribution": "awk",
    "explanation": "awk splits each line into fields on whitespace. $1 is the first, $NF the last - so this prints the first and last column of every line.",
    "content": "awk '{print $1, $NF}' access.log"
  },
  {
    "category": "shell",
    "language": "shell",
    "attribution": "awk",
    "explanation": "-F sets the field separator. This reads /etc/passwd and prints the username and shell, which are fields 1 and 7.",
    "content": "awk -F: '{print $1, $7}' /etc/passwd"
  },
  {
    "category": "shell",
    "language": "shell",
    "attribution": "awk",
    "explanation": "A pattern before the block acts as a filter: only lines whose 9th field is 404 are printed. No grep needed.",
    "content": "awk '$9 == 404 {print $7}' access.log | sort | uniq -c | sort -rn"
  },
  {
    "category": "shell",
    "language": "shell",
    "attribution": "awk",
    "explanation": "Associative arrays are awk's real power. This sums bytes per IP in one pass, then END prints the totals once input is exhausted.",
    "content": "awk '{bytes[$1] += $10} END {for (ip in bytes) print bytes[ip], ip}' access.log | sort -rn | head"
  },
  {
    "category": "shell",
    "language": "shell",
    "attribution": "awk",
    "explanation": "NR is the current line number, NF the field count. This finds malformed rows: any line that does not have exactly three fields.",
    "content": "awk -F, 'NF != 3 {print NR\": \"$0}' data.csv"
  },
  {
    "category": "shell",
    "language": "shell",
    "attribution": "awk",
    "explanation": "Deduplicate without sorting, preserving original order. The array records what has been seen; !seen[$0]++ is true only the first time.",
    "content": "awk '!seen[$0]++' file.txt"
  },
  {
    "category": "shell",
    "language": "shell",
    "attribution": "awk",
    "explanation": "Sums a column and prints the average. END runs after the last line, so NR is the total row count by then.",
    "content": "awk '{sum += $3} END {print sum, sum/NR}' numbers.txt"
  },
  {
    "category": "shell",
    "language": "shell",
    "attribution": "sed",
    "explanation": "Substitute in place. The g flag replaces every match on a line, not just the first; -i writes the file rather than printing.",
    "content": "sed -i 's/localhost/127.0.0.1/g' config.ini"
  },
  {
    "category": "shell",
    "language": "shell",
    "attribution": "sed",
    "explanation": "Prints only lines 10 to 20. -n suppresses the default print, and p prints the range that matched.",
    "content": "sed -n '10,20p' large.log"
  },
  {
    "category": "shell",
    "language": "shell",
    "attribution": "sed",
    "explanation": "Deletes comments and blank lines, which is how you read a config that is mostly documentation.",
    "content": "sed -e 's/#.*//' -e '/^[[:space:]]*$/d' /etc/ssh/sshd_config"
  },
  {
    "category": "shell",
    "language": "shell",
    "attribution": "Pipelines",
    "explanation": "The classic word-frequency pipeline: split to one word per line, fold case, sort so duplicates are adjacent, count runs, order by count.",
    "content": "tr -cs '[:alpha:]' '\\n' < book.txt | tr 'A-Z' 'a-z' | sort | uniq -c | sort -rn | head -20"
  },
  {
    "category": "shell",
    "language": "shell",
    "attribution": "Pipelines",
    "explanation": "uniq only collapses adjacent duplicates, which is why sort comes first. -c counts, and the second sort orders by that count.",
    "content": "cut -d' ' -f1 access.log | sort | uniq -c | sort -rn | head"
  },
  {
    "category": "shell",
    "language": "shell",
    "attribution": "Pipelines",
    "explanation": "xargs turns a stream of names into arguments. -0 with -print0 is what makes filenames containing spaces safe.",
    "content": "find . -name '*.log' -print0 | xargs -0 grep -l 'ERROR'"
  },
  {
    "category": "shell",
    "language": "shell",
    "attribution": "Pipelines",
    "explanation": "Runs a command per input line in parallel. -P4 keeps four running at once, and -I{} places each name where the braces are.",
    "content": "ls *.png | xargs -P4 -I{} convert {} -resize 50% small/{}"
  },
  {
    "category": "shell",
    "language": "shell",
    "attribution": "Pipelines",
    "explanation": "Process substitution gives two commands to diff as if they were files, without writing either to disk.",
    "content": "diff <(sort a.txt) <(sort b.txt)"
  },
  {
    "category": "shell",
    "language": "shell",
    "attribution": "Pipelines",
    "explanation": "tee writes to a file and passes the stream on, so you can log and keep processing in the same pipeline.",
    "content": "make 2>&1 | tee build.log | grep -E 'error|warning'"
  },
  {
    "category": "shell",
    "language": "shell",
    "attribution": "Pipelines",
    "explanation": "comm compares two sorted files by column: -13 shows only lines unique to the second, which is the set that was added.",
    "content": "comm -13 <(sort old.txt) <(sort new.txt)"
  },
  {
    "category": "shell",
    "language": "shell",
    "attribution": "Pipelines",
    "explanation": "jq selects and reshapes JSON. -r prints raw strings, so the output is usable by the next command rather than quoted.",
    "content": "curl -s https://api.example.com/users | jq -r '.[] | select(.active) | .email'"
  },
  {
    "category": "shell",
    "language": "shell",
    "attribution": "Text processing",
    "explanation": "grep -o prints only the match, one per line, which turns a search into a stream you can count.",
    "content": "grep -oE '[0-9]{1,3}(\\.[0-9]{1,3}){3}' access.log | sort -u | wc -l"
  },
  {
    "category": "shell",
    "language": "shell",
    "attribution": "Text processing",
    "explanation": "paste joins lines side by side; -s -d joins them all into one line with the chosen separator.",
    "content": "cut -f2 data.tsv | paste -sd, -"
  },
  {
    "category": "shell",
    "language": "shell",
    "attribution": "Text processing",
    "explanation": "column formats whitespace-separated input into aligned columns, which makes an unreadable log readable.",
    "content": "mount | column -t | grep -v tmpfs"
  },
  {
    "category": "shell",
    "language": "shell",
    "attribution": "Shell safety",
    "explanation": "The unofficial strict mode: exit on error, exit on undefined variable, and fail a pipeline if any stage fails rather than only the last.",
    "content": "set -euo pipefail"
  },
  {
    "category": "shell",
    "language": "shell",
    "attribution": "Shell safety",
    "explanation": "Quoting \"$@\" preserves each argument exactly, including ones containing spaces. Unquoted $@ splits them apart.",
    "content": "for f in \"$@\"; do printf '%s\\n' \"${f%.*}\"; done"
  },
  {
    "category": "shell",
    "language": "shell",
    "attribution": "Shell safety",
    "explanation": "A trap on EXIT cleans up whether the script succeeded, failed or was interrupted.",
    "content": "tmp=$(mktemp -d) && trap 'rm -rf \"$tmp\"' EXIT"
  },
  {
    "category": "shell",
    "content": "awk -F: '$3 >= 1000 && $7 !~ /nologin|false/ {print $1, $6}' /etc/passwd",
    "attribution": "awk",
    "explanation": "Two conditions joined with &&. $3 >= 1000 keeps ordinary user accounts, and !~ excludes any shell matching nologin or false, so what is left is the humans who can log in.",
    "language": "shell"
  },
  {
    "category": "shell",
    "content": "awk '{sum += $1; n++} END {if (n) printf \"%.2f\\n\", sum / n}' numbers.txt",
    "attribution": "awk",
    "explanation": "Variables in awk need no declaration and start at zero. END runs once after the last line, so this accumulates while reading and prints the mean at the finish.",
    "language": "shell"
  },
  {
    "category": "shell",
    "content": "awk 'NR == FNR {seen[$1]; next} !($1 in seen)' first.txt second.txt",
    "attribution": "awk",
    "explanation": "NR is the overall line number and FNR restarts per file, so NR == FNR is true only while reading the first file. This prints lines of the second file whose first field never appeared in the first.",
    "language": "shell"
  },
  {
    "category": "shell",
    "content": "sort access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -20",
    "attribution": "shell",
    "explanation": "uniq -c counts runs of identical adjacent lines, which is why the sort before it is required. sort -rn then orders those counts highest first, giving the twenty busiest addresses.",
    "language": "shell"
  },
  {
    "category": "shell",
    "content": "find . -type f -name '*.log' -mtime +30 -print0 | xargs -0 rm -v",
    "attribution": "find",
    "explanation": "-print0 separates paths with a null byte and -0 tells xargs to expect that, which is the only safe way to pass file names containing spaces or newlines.",
    "language": "shell"
  },
  {
    "category": "shell",
    "content": "grep -rn --include='*.rs' -e 'unwrap()' -e 'expect(' src/ | wc -l",
    "attribution": "grep",
    "explanation": "-r walks the tree, --include limits it to one file type, and repeated -e adds alternative patterns. Counting the result gives a rough measure of how much error handling is deferred.",
    "language": "shell"
  },
  {
    "category": "shell",
    "content": "sed -i.bak -E 's/([0-9]{4})-([0-9]{2})-([0-9]{2})/\\3\\/\\2\\/\\1/g' dates.csv",
    "attribution": "sed",
    "explanation": "-i.bak edits in place and keeps the original alongside. The parenthesised groups are recalled as \\1, \\2 and \\3, which is how the date order is rearranged.",
    "language": "shell"
  },
  {
    "category": "shell",
    "content": "tar czf - /var/www | ssh backup@host 'cat > site-$(date +%F).tar.gz'",
    "attribution": "tar",
    "explanation": "A dash as the file name makes tar write to standard output. The archive is never stored locally: it streams straight down the ssh connection into a file on the far side.",
    "language": "shell"
  },
  {
    "category": "shell",
    "content": "ps -eo pid,ppid,rss,comm --sort=-rss | head -15",
    "attribution": "ps",
    "explanation": "-eo picks exactly which columns to print. rss is resident memory in kilobytes, and the minus sign in --sort reverses the order, so the heaviest processes come first.",
    "language": "shell"
  },
  {
    "category": "shell",
    "content": "diff <(sort a.txt) <(sort b.txt) | grep '^[<>]'",
    "attribution": "shell",
    "explanation": "Process substitution gives each command a file name of its own, so diff can compare two pipelines without either being written to disk first.",
    "language": "shell"
  },
  {
    "category": "shell",
    "content": "curl -sS -w '%{http_code} %{time_total}s\\n' -o /dev/null https://example.com",
    "attribution": "curl",
    "explanation": "-o /dev/null throws the body away while -w prints chosen variables, which turns curl into a quick check of status and latency alone.",
    "language": "shell"
  },
  {
    "category": "shell",
    "content": "journalctl -u nginx --since '1 hour ago' -p err --no-pager | tail -50",
    "attribution": "journalctl",
    "explanation": "-p err keeps only entries at error priority or worse. --no-pager matters in a script, where an interactive pager would otherwise wait for a keypress that never comes.",
    "language": "shell"
  }
]