<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>ShellonDocs</title><link>https://hiraethecho.github.io/docs/tags/shell/</link><description>Recent contentinShellonDocs</description><generator>Hugo --0.152.2</generator><language>en</language><managingEditor>wyz2016zxc@outlook.com(Hiraeth)</managingEditor><webMaster>wyz2016zxc@outlook.com(Hiraeth)</webMaster><lastBuildDate>Mon, 16 Mar 2026 15:39:39 +0800</lastBuildDate><atom:link href="https://hiraethecho.github.io/docs/tags/shell/index.xml" rel="self" type="application/rss+xml"/><item><title>linux手册</title><link>https://hiraethecho.github.io/docs/linux/linux-handbook/</link><pubDate>Sat, 25 Oct 2025 00:00:00 +0000</pubDate><author>wyz2016zxc@outlook.com(Hiraeth)</author><guid>https://hiraethecho.github.io/docs/linux/linux-handbook/</guid><description>&lt;h1 id="linux-handbook"&gt;
&lt;a class="anchor inpage" href="#linux-handbook"&gt;#&lt;/a&gt;Linux Handbook&lt;/h1&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;details open&gt;
&lt;summary&gt;TEXT&lt;/summary&gt;&lt;pre
class="codeblock"
&gt;&lt;code class="language-" data-lang=""&gt;bash &amp;lt;(curl -sSL https://linuxmirrors.cn/main.sh)&lt;/code&gt;&lt;button onclick="copyCode(this)" class="copybtn"&gt;copy&lt;/button&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;script&gt;
function copyCode(btn) {
const code = btn.previousElementSibling.textContent.trim();
navigator.clipboard.writeText(code).then(() =&gt; {
btn.innerText = "copied";
setTimeout(() =&gt; (btn.innerText = "copy"), 2000);
});
}
&lt;/script&gt;&lt;details open&gt;
&lt;summary&gt;TEXT&lt;/summary&gt;&lt;pre
class="codeblock"
&gt;&lt;code class="language-" data-lang=""&gt;bash &amp;lt;(curl -sSL https://linuxmirrors.cn/docker.sh)&lt;/code&gt;&lt;button onclick="copyCode(this)" class="copybtn"&gt;copy&lt;/button&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;script&gt;
function copyCode(btn) {
const code = btn.previousElementSibling.textContent.trim();
navigator.clipboard.writeText(code).then(() =&gt; {
btn.innerText = "copied";
setTimeout(() =&gt; (btn.innerText = "copy"), 2000);
});
}
&lt;/script&gt;&lt;details open&gt;
&lt;summary&gt;TEXT&lt;/summary&gt;&lt;pre
class="codeblock"
&gt;&lt;code class="language-" data-lang=""&gt;bash &amp;lt;(curl -sSL https://linuxmirrors.cn/docker.sh) --only-registry&lt;/code&gt;&lt;button onclick="copyCode(this)" class="copybtn"&gt;copy&lt;/button&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;script&gt;
function copyCode(btn) {
const code = btn.previousElementSibling.textContent.trim();
navigator.clipboard.writeText(code).then(() =&gt; {
btn.innerText = "copied";
setTimeout(() =&gt; (btn.innerText = "copy"), 2000);
});
}
&lt;/script&gt;&lt;h2 id="file"&gt;
&lt;a class="anchor inpage" href="#file"&gt;##&lt;/a&gt;file&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;filedialog&lt;/code&gt; 是其他应用需要选择文件时的弹窗&lt;/p&gt;</description><content:encoded><![CDATA[<h1 id="linux-handbook">
  <a class="anchor inpage" href="#linux-handbook">#</a>Linux Handbook</h1>
<p>
</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">bash &lt;(curl -sSL https://linuxmirrors.cn/main.sh)</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">bash &lt;(curl -sSL https://linuxmirrors.cn/docker.sh)</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">bash &lt;(curl -sSL https://linuxmirrors.cn/docker.sh) --only-registry</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h2 id="file">
  <a class="anchor inpage" href="#file">##</a>file</h2>
<p><code>filedialog</code> 是其他应用需要选择文件时的弹窗</p>
<h2 id="boot">
  <a class="anchor inpage" href="#boot">##</a>boot</h2>
<h2 id="display-manager">
  <a class="anchor inpage" href="#display-manager">##</a>display manager</h2>
<p>lightdm 有一堆莫名其妙的问题</p>
<p>gtk display还不知道怎么搞</p>
<h2 id="keyring">
  <a class="anchor inpage" href="#keyring">##</a>keyring</h2>
<p>
</p>
<p>use <code>gnome-keyring</code> and <code>thunar</code> to auto connect a webdav.

</p>
<h2 id="reference">
  <a class="anchor inpage" href="#reference">##</a>Reference</h2>
<p>
</p>
<h2 id="commands">
  <a class="anchor inpage" href="#commands">##</a>commands</h2>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>type something</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>example</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>type cd
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>cd is a shell builtin</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h2 id="技巧">
  <a class="anchor inpage" href="#%e6%8a%80%e5%b7%a7">##</a>技巧</h2>
<details open>
    <summary>tldr</summary><pre
        class="codeblock"
      ><code class="language-tldr" data-lang="tldr">  Change attributes of files or directories.
  More information: &lt;https://manned.org/chattr&gt;.

  Make a file or directory [i]mmutable to changes and deletion, even by superuser:

      chattr &#43;i path/to/file_or_directory

  Make a file or directory mutable:

      chattr -i path/to/file_or_directory

  [R]ecursively make an entire directory and contents immutable:

      chattr -R &#43;i path/to/directory

  Mark a directory and its files to be interpreted in a case-insensitive manner (case-[F]olding):

      chattr &#43;F path/to/directory

  Set a file to only allow [a]ppending:

      chattr &#43;a path/to/file</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script>]]></content:encoded></item><item><title>一些sh脚本</title><link>https://hiraethecho.github.io/docs/dev/scripts-example/</link><pubDate>Sat, 25 Oct 2025 00:00:00 +0000</pubDate><author>wyz2016zxc@outlook.com(Hiraeth)</author><guid>https://hiraethecho.github.io/docs/dev/scripts-example/</guid><description>&lt;h1 id="scripts-example"&gt;
&lt;a class="anchor inpage" href="#scripts-example"&gt;#&lt;/a&gt;scripts example&lt;/h1&gt;
&lt;details open&gt;
&lt;summary&gt;TEXT&lt;/summary&gt;&lt;pre
class="codeblock"
&gt;&lt;code class="language-" data-lang=""&gt;find . -name &amp;#34;*.md&amp;#34; -type f -exec grep -lE &amp;#34;Finished&amp;#34; {} &amp;#43; | while read file; do
if ! grep -q &amp;#34;2025-05-31&amp;#34; &amp;#34;$file&amp;#34;; then
number=$(awk &amp;#39;/^pages: [0-9]&amp;#43;/ {print $2}&amp;#39; &amp;#34;$file&amp;#34;)
if [ -n &amp;#34;$number&amp;#34; ]; then
sed -i &amp;#34;/Finished/i\\- 2025-05-31: $number&amp;#34; &amp;#34;$file&amp;#34;
echo &amp;#34;已处理: $file - 插入: - 2025-05-31: $number&amp;#34;
else
echo &amp;#34;跳过: $file (未找到pages数字或有效日期)&amp;#34;
fi
else
echo &amp;#34;排除: $file (包含 2025-05-31)&amp;#34;
fi
done&lt;/code&gt;&lt;button onclick="copyCode(this)" class="copybtn"&gt;copy&lt;/button&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;script&gt;
function copyCode(btn) {
const code = btn.previousElementSibling.textContent.trim();
navigator.clipboard.writeText(code).then(() =&gt; {
btn.innerText = "copied";
setTimeout(() =&gt; (btn.innerText = "copy"), 2000);
});
}
&lt;/script&gt;&lt;details open&gt;
&lt;summary&gt;TEXT&lt;/summary&gt;&lt;pre
class="codeblock"
&gt;&lt;code class="language-" data-lang=""&gt;# 创建备份和日志
backup_dir=&amp;#34;backup_$(date &amp;#43;%Y%m%d)&amp;#34;
mkdir -p &amp;#34;$backup_dir&amp;#34;
log_file=&amp;#34;replace_log.txt&amp;#34;
echo &amp;#34;开始替换操作 $(date)&amp;#34; &amp;gt; &amp;#34;$log_file&amp;#34;
find . -name &amp;#34;*.md&amp;#34; -type f | while read file; do
# 检查文件是否包含目标字符串
if grep -q &amp;#34;- 2025-06-01: Finished&amp;#34; &amp;#34;$file&amp;#34;; then
# 创建备份
cp &amp;#34;$file&amp;#34; &amp;#34;$backup_dir/$(basename &amp;#34;$file&amp;#34;)&amp;#34;
# 执行替换
sed -i &amp;#39;s/- 2025-06-01: Finished/- 2025-05-31: Finished/g&amp;#39; &amp;#34;$file&amp;#34;
# 记录日志
echo &amp;#34;已修改: $file&amp;#34; &amp;gt;&amp;gt; &amp;#34;$log_file&amp;#34;
# 显示变更
echo &amp;#34;=== $file 修改内容 ===&amp;#34;
diff &amp;#34;$backup_dir/$(basename &amp;#34;$file&amp;#34;)&amp;#34; &amp;#34;$file&amp;#34; || true
else
echo &amp;#34;无修改: $file&amp;#34; &amp;gt;&amp;gt; &amp;#34;$log_file&amp;#34;
fi
done
echo &amp;#34;操作完成，备份在 $backup_dir，日志见 $log_file&amp;#34;&lt;/code&gt;&lt;button onclick="copyCode(this)" class="copybtn"&gt;copy&lt;/button&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;script&gt;
function copyCode(btn) {
const code = btn.previousElementSibling.textContent.trim();
navigator.clipboard.writeText(code).then(() =&gt; {
btn.innerText = "copied";
setTimeout(() =&gt; (btn.innerText = "copy"), 2000);
});
}
&lt;/script&gt;&lt;details open&gt;
&lt;summary&gt;TEXT&lt;/summary&gt;&lt;pre
class="codeblock"
&gt;&lt;code class="language-" data-lang=""&gt;find . -name &amp;#34;*.md&amp;#34; -type f -exec grep -l &amp;#34;lists: book&amp;#34; {} &amp;#43; | \
while read file; do
if ! grep -q &amp;#34;Finished&amp;#34; &amp;#34;$file&amp;#34;; then
# 确保文件末尾有空行（避免追加内容粘连）
[ -n &amp;#34;$(tail -c 1 &amp;#34;$file&amp;#34;)&amp;#34; ] &amp;amp;&amp;amp; echo &amp;gt;&amp;gt; &amp;#34;$file&amp;#34;
# 追加内容
echo &amp;#34;- 2025-06-01: Finished&amp;#34; &amp;gt;&amp;gt; &amp;#34;$file&amp;#34;
echo &amp;#34;已处理: $file&amp;#34;
else
echo &amp;#34;跳过: $file (已包含 Finished)&amp;#34;
fi
done&lt;/code&gt;&lt;button onclick="copyCode(this)" class="copybtn"&gt;copy&lt;/button&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;script&gt;
function copyCode(btn) {
const code = btn.previousElementSibling.textContent.trim();
navigator.clipboard.writeText(code).then(() =&gt; {
btn.innerText = "copied";
setTimeout(() =&gt; (btn.innerText = "copy"), 2000);
});
}
&lt;/script&gt;&lt;details open&gt;
&lt;summary&gt;TEXT&lt;/summary&gt;&lt;pre
class="codeblock"
&gt;&lt;code class="language-" data-lang=""&gt;find . -name &amp;#34;*.md&amp;#34; -type f -exec grep -L &amp;#34;Finished&amp;#34; {} &amp;#43; | while read file; do
awk &amp;#39;BEGIN {done=0} /^---/ &amp;amp;&amp;amp; !done {print; print &amp;#34;- 2025-06-01: Finished&amp;#34;; done=1; next} 1&amp;#39; &amp;#34;$file&amp;#34; &amp;gt; tmp &amp;amp;&amp;amp; mv tmp &amp;#34;$file&amp;#34;
done&lt;/code&gt;&lt;button onclick="copyCode(this)" class="copybtn"&gt;copy&lt;/button&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;script&gt;
function copyCode(btn) {
const code = btn.previousElementSibling.textContent.trim();
navigator.clipboard.writeText(code).then(() =&gt; {
btn.innerText = "copied";
setTimeout(() =&gt; (btn.innerText = "copy"), 2000);
});
}
&lt;/script&gt;</description><content:encoded><![CDATA[<h1 id="scripts-example">
  <a class="anchor inpage" href="#scripts-example">#</a>scripts example</h1>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">find . -name &#34;*.md&#34; -type f -exec grep -lE &#34;Finished&#34; {} &#43; | while read file; do
  if ! grep -q &#34;2025-05-31&#34; &#34;$file&#34;; then
    number=$(awk &#39;/^pages: [0-9]&#43;/ {print $2}&#39; &#34;$file&#34;)
    if [ -n &#34;$number&#34; ]; then
      sed -i &#34;/Finished/i\\- 2025-05-31: $number&#34; &#34;$file&#34;
      echo &#34;已处理: $file - 插入: - 2025-05-31: $number&#34;
    else
      echo &#34;跳过: $file (未找到pages数字或有效日期)&#34;
    fi
  else
    echo &#34;排除: $file (包含 2025-05-31)&#34;
  fi
done</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang=""># 创建备份和日志
backup_dir=&#34;backup_$(date &#43;%Y%m%d)&#34;
mkdir -p &#34;$backup_dir&#34;
log_file=&#34;replace_log.txt&#34;

echo &#34;开始替换操作 $(date)&#34; &gt; &#34;$log_file&#34;

find . -name &#34;*.md&#34; -type f | while read file; do
    # 检查文件是否包含目标字符串
    if grep -q &#34;- 2025-06-01: Finished&#34; &#34;$file&#34;; then
        # 创建备份
        cp &#34;$file&#34; &#34;$backup_dir/$(basename &#34;$file&#34;)&#34;
        # 执行替换
        sed -i &#39;s/- 2025-06-01: Finished/- 2025-05-31: Finished/g&#39; &#34;$file&#34;
        # 记录日志
        echo &#34;已修改: $file&#34; &gt;&gt; &#34;$log_file&#34;
        # 显示变更
        echo &#34;=== $file 修改内容 ===&#34;
        diff &#34;$backup_dir/$(basename &#34;$file&#34;)&#34; &#34;$file&#34; || true
    else
        echo &#34;无修改: $file&#34; &gt;&gt; &#34;$log_file&#34;
    fi
done

echo &#34;操作完成，备份在 $backup_dir，日志见 $log_file&#34;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">find . -name &#34;*.md&#34; -type f -exec grep -l &#34;lists: book&#34; {} &#43; | \
while read file; do
    if ! grep -q &#34;Finished&#34; &#34;$file&#34;; then
        # 确保文件末尾有空行（避免追加内容粘连）
        [ -n &#34;$(tail -c 1 &#34;$file&#34;)&#34; ] &amp;&amp; echo &gt;&gt; &#34;$file&#34;
        # 追加内容
        echo &#34;- 2025-06-01: Finished&#34; &gt;&gt; &#34;$file&#34;
        echo &#34;已处理: $file&#34;
    else
        echo &#34;跳过: $file (已包含 Finished)&#34;
    fi
done</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">find . -name &#34;*.md&#34; -type f -exec grep -L &#34;Finished&#34; {} &#43; | while read file; do
    awk &#39;BEGIN {done=0} /^---/ &amp;&amp; !done {print; print &#34;- 2025-06-01: Finished&#34;; done=1; next} 1&#39; &#34;$file&#34; &gt; tmp &amp;&amp; mv tmp &#34;$file&#34;
done</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script>]]></content:encoded></item><item><title>cli收集</title><link>https://hiraethecho.github.io/docs/dev/cli/</link><pubDate>Thu, 23 Oct 2025 00:00:00 +0000</pubDate><author>wyz2016zxc@outlook.com(Hiraeth)</author><guid>https://hiraethecho.github.io/docs/dev/cli/</guid><description>收集一些cli的命令工具用法</description><content:encoded><![CDATA[<h1 id="cli收集">
  <a class="anchor inpage" href="#cli%e6%94%b6%e9%9b%86">#</a>cli收集</h1>
<h2 id="utils">
  <a class="anchor inpage" href="#utils">##</a>utils</h2>
<p>一些基础的，常常是系统自带的命令工具。</p>
<h3 id="chattr">
  <a class="anchor inpage" href="#chattr">###</a>chattr</h3>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">sudo chattr &#43;i /etc/resolv.conf  # 设置文件不可修改
sudo chattr -i /etc/resolv.conf  # 解除</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="file">
  <a class="anchor inpage" href="#file">###</a>file</h3>
<p>use following to find file type. <code>-L</code> means follow the symbolic link</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">file --mime-type -L file</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>use following shell scripts to set mime (need rofi)</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span><span style="color:#75715e">#!/bin/sh
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>
</span></span><span style="display:flex;"><span>FILETYPE<span style="color:#f92672">=</span><span style="color:#66d9ef">$(</span>xdg-mime query filetype $1<span style="color:#66d9ef">)</span>
</span></span><span style="display:flex;"><span>APP<span style="color:#f92672">=</span><span style="color:#66d9ef">$(</span> find /usr/share -type f -name <span style="color:#e6db74">&#34;*.desktop&#34;</span> -printf <span style="color:#e6db74">&#34;%p\n&#34;</span> | sed <span style="color:#e6db74">&#39;s/\/.*\///g&#39;</span> | rofi -threads <span style="color:#ae81ff">0</span> -dmenu -i -p <span style="color:#e6db74">&#34;select default app&#34;</span><span style="color:#66d9ef">)</span>
</span></span><span style="display:flex;"><span>echo $APP
</span></span><span style="display:flex;"><span>xdg-mime default <span style="color:#e6db74">&#34;</span>$APP<span style="color:#e6db74">&#34;</span> <span style="color:#e6db74">&#34;</span>$FILETYPE<span style="color:#e6db74">&#34;</span>
</span></span><span style="display:flex;"><span>echo <span style="color:#e6db74">&#34;</span>$APP<span style="color:#e6db74"> set as default application to open </span>$FILETYPE<span style="color:#e6db74">&#34;</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="stat">
  <a class="anchor inpage" href="#stat">###</a>stat</h3>
<p><code>stat</code>展示文件状态，例如</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">stat /

  File: /
  Size: 122       	Blocks: 0          IO Block: 4096   directory
Device: 0,28	Inode: 256         Links: 1
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2025-05-10 23:46:03.122616066 &#43;0800
Modify: 2025-05-11 21:26:49.474145593 &#43;0800
Change: 2025-05-11 21:26:49.474145593 &#43;0800
 Birth: 2025-01-01 14:58:38.377746860 &#43;0800</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="type">
  <a class="anchor inpage" href="#type">###</a>type</h3>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">  Display the type of command the shell will execute.
  Note: All examples are not POSIX compliant.
  More information: &lt;https://www.gnu.org/software/bash/manual/bash.html#index-type&gt;.

  Display the type of a command:

      type command

  Display all locations containing the specified executable (works only in Bash/fish/Zsh shells):

      type -a command

  Display the name of the disk file that would be executed (works only in Bash/fish/Zsh shells):

      type -p command

  Display the type of a specific command, alias/keyword/function/builtin/file (works only in Bash/fish shells):

      type -t command</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="date">
  <a class="anchor inpage" href="#date">###</a>date</h3>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">Usage: date [OPTION]... [&#43;FORMAT]
  or:  date [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]]
Display date and time in the given FORMAT.
With -s, or with [MMDDhhmm[[CC]YY][.ss]], set the date and time.

Mandatory arguments to long options are mandatory for short options too.
  -d, --date=STRING          display time described by STRING, not &#39;now&#39;
      --debug                annotate the parsed date,
                              and warn about questionable usage to stderr
  -f, --file=DATEFILE        like --date; once for each line of DATEFILE
  -I[FMT], --iso-8601[=FMT]  output date/time in ISO 8601 format.
                               FMT=&#39;date&#39; for date only (the default),
                               &#39;hours&#39;, &#39;minutes&#39;, &#39;seconds&#39;, or &#39;ns&#39;
                               for date and time to the indicated precision.
                               Example: 2006-08-14T02:34:56-06:00
  --resolution               output the available resolution of timestamps
                               Example: 0.000000001
  -R, --rfc-email            output date and time in RFC 5322 format.
                               Example: Mon, 14 Aug 2006 02:34:56 -0600
      --rfc-3339=FMT         output date/time in RFC 3339 format.
                               FMT=&#39;date&#39;, &#39;seconds&#39;, or &#39;ns&#39;
                               for date and time to the indicated precision.
                               Example: 2006-08-14 02:34:56-06:00
  -r, --reference=FILE       display the last modification time of FILE
  -s, --set=STRING           set time described by STRING
  -u, --utc, --universal     print or set Coordinated Universal Time (UTC)
      --help        display this help and exit
      --version     output version information and exit

All options that specify the date to display are mutually exclusive.
I.e.: --date, --file, --reference, --resolution.

FORMAT controls the output.  Interpreted sequences are:

  %%   a literal %
  %a   locale&#39;s abbreviated weekday name (e.g., Sun)
  %A   locale&#39;s full weekday name (e.g., Sunday)
  %b   locale&#39;s abbreviated month name (e.g., Jan)
  %B   locale&#39;s full month name (e.g., January)
  %c   locale&#39;s date and time (e.g., Thu Mar  3 23:05:25 2005)
  %C   century; like %Y, except omit last two digits (e.g., 20)
  %d   day of month (e.g., 01)
  %D   date (ambiguous); same as %m/%d/%y
  %e   day of month, space padded; same as %_d
  %F   full date; like %&#43;4Y-%m-%d
  %g   last two digits of year of ISO week number (ambiguous; 00-99); see %G
  %G   year of ISO week number; normally useful only with %V
  %h   same as %b
  %H   hour (00..23)
  %I   hour (01..12)
  %j   day of year (001..366)
  %k   hour, space padded ( 0..23); same as %_H
  %l   hour, space padded ( 1..12); same as %_I
  %m   month (01..12)
  %M   minute (00..59)
  %n   a newline
  %N   nanoseconds (000000000..999999999)
  %p   locale&#39;s equivalent of either AM or PM; blank if not known
  %P   like %p, but lower case
  %q   quarter of year (1..4)
  %r   locale&#39;s 12-hour clock time (e.g., 11:11:04 PM)
  %R   24-hour hour and minute; same as %H:%M
  %s   seconds since the Epoch (1970-01-01 00:00 UTC)
  %S   second (00..60)
  %t   a tab
  %T   time; same as %H:%M:%S
  %u   day of week (1..7); 1 is Monday
  %U   week number of year, with Sunday as first day of week (00..53)
  %V   ISO week number, with Monday as first day of week (01..53)
  %w   day of week (0..6); 0 is Sunday
  %W   week number of year, with Monday as first day of week (00..53)
  %x   locale&#39;s date (can be ambiguous; e.g., 12/31/99)
  %X   locale&#39;s time representation (e.g., 23:13:48)
  %y   last two digits of year (ambiguous; 00..99)
  %Y   year
  %z   &#43;hhmm numeric time zone (e.g., -0400)
  %:z  &#43;hh:mm numeric time zone (e.g., -04:00)
  %::z  &#43;hh:mm:ss numeric time zone (e.g., -04:00:00)
  %:::z  numeric time zone with : to necessary precision (e.g., -04, &#43;05:30)
  %Z   alphabetic time zone abbreviation (e.g., EDT)

By default, date pads numeric fields with zeroes.
The following optional flags may follow &#39;%&#39;:

  -  (hyphen) do not pad the field
  _  (underscore) pad with spaces
  0  (zero) pad with zeros
  &#43;  pad with zeros, and put &#39;&#43;&#39; before future years with &gt;4 digits
  ^  use upper case if possible
  #  use opposite case if possible

After any flags comes an optional field width, as a decimal number;
then an optional modifier, which is either
E to use the locale&#39;s alternate representations if available, or
O to use the locale&#39;s alternate numeric symbols if available.

Examples:
Convert seconds since the Epoch (1970-01-01 UTC) to a date
  $ date --date=&#39;@2147483647&#39;

Show the time on the west coast of the US (use tzselect(1) to find TZ)
  $ TZ=&#39;America/Los_Angeles&#39; date

Show the local time for 9AM next Friday on the west coast of the US
  $ date --date=&#39;TZ=&#34;America/Los_Angeles&#34; 09:00 next Fri&#39;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h2 id="tricks">
  <a class="anchor inpage" href="#tricks">##</a>tricks</h2>
<p>后台挂起</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>nohup onedrivegui &amp; &gt; /dev/null</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script>]]></content:encoded></item><item><title>awk</title><link>https://hiraethecho.github.io/docs/dev/awk/</link><pubDate>Mon, 05 May 2025 00:00:00 +0000</pubDate><author>wyz2016zxc@outlook.com(Hiraeth)</author><guid>https://hiraethecho.github.io/docs/dev/awk/</guid><description>&lt;h1 id="awk"&gt;
&lt;a class="anchor inpage" href="#awk"&gt;#&lt;/a&gt;awk&lt;/h1&gt;
&lt;h2 id="tldr"&gt;
&lt;a class="anchor inpage" href="#tldr"&gt;##&lt;/a&gt;tldr&lt;/h2&gt;
&lt;p&gt;A versatile programming language for working on files.
More information:
.&lt;/p&gt;
&lt;p&gt;Print the fifth column (a.k.a. field) in a space-separated file:&lt;/p&gt;
&lt;details open&gt;
&lt;summary&gt;TEXT&lt;/summary&gt;&lt;pre
class="codeblock"
&gt;&lt;code class="language-" data-lang=""&gt;awk &amp;#39;{print $5}&amp;#39; path/to/file&lt;/code&gt;&lt;button onclick="copyCode(this)" class="copybtn"&gt;copy&lt;/button&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;script&gt;
function copyCode(btn) {
const code = btn.previousElementSibling.textContent.trim();
navigator.clipboard.writeText(code).then(() =&gt; {
btn.innerText = "copied";
setTimeout(() =&gt; (btn.innerText = "copy"), 2000);
});
}
&lt;/script&gt;&lt;p&gt;Print the second column of the lines containing &amp;ldquo;foo&amp;rdquo; in a space-separated file:&lt;/p&gt;
&lt;details open&gt;
&lt;summary&gt;TEXT&lt;/summary&gt;&lt;pre
class="codeblock"
&gt;&lt;code class="language-" data-lang=""&gt;awk &amp;#39;/foo/ {print $2}&amp;#39; path/to/file&lt;/code&gt;&lt;button onclick="copyCode(this)" class="copybtn"&gt;copy&lt;/button&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;script&gt;
function copyCode(btn) {
const code = btn.previousElementSibling.textContent.trim();
navigator.clipboard.writeText(code).then(() =&gt; {
btn.innerText = "copied";
setTimeout(() =&gt; (btn.innerText = "copy"), 2000);
});
}
&lt;/script&gt;&lt;p&gt;Print the last column of each line in a file, using a comma (instead of space) as a field separator:&lt;/p&gt;</description><content:encoded><![CDATA[<h1 id="awk">
  <a class="anchor inpage" href="#awk">#</a>awk</h1>
<h2 id="tldr">
  <a class="anchor inpage" href="#tldr">##</a>tldr</h2>
<p>A versatile programming language for working on files.
More information: 
.</p>
<p>Print the fifth column (a.k.a. field) in a space-separated file:</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk &#39;{print $5}&#39; path/to/file</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Print the second column of the lines containing &ldquo;foo&rdquo; in a space-separated file:</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk &#39;/foo/ {print $2}&#39; path/to/file</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Print the last column of each line in a file, using a comma (instead of space) as a field separator:</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk -F &#39;,&#39; &#39;{print $NF}&#39; path/to/file</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Sum the values in the first column of a file and print the total:</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk &#39;{s&#43;=$1} END {print s}&#39; path/to/file</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Print every third line starting from the first line:</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk &#39;NR%3==1&#39; path/to/file</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Print different values based on conditions:</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk &#39;{if ($1 == &#34;foo&#34;) print &#34;Exact match foo&#34;; else if ($1 ~ &#34;bar&#34;) print &#34;Partial match bar&#34;; else print &#34;Baz&#34;}&#39; path/to/file</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Print all the lines which the 10th column value is between a min and a max:</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk &#39;($10 &gt;= min_value &amp;&amp; $10 &lt;= max_value)&#39;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Print table of users with UID &gt;=1000 with header and formatted output, using colon as separator (<code>%-20s</code> mean: 20 left-align string characters, <code>%6s</code> means: 6 right-align string characters):</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk &#39;BEGIN {FS=&#34;:&#34;;printf &#34;%-20s %6s %25s\n&#34;, &#34;Name&#34;, &#34;UID&#34;, &#34;Shell&#34;} $4 &gt;= 1000 {printf &#34;%-20s %6d %25s\n&#34;, $1, $4, $7}&#39; /etc/passwd</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h2 id="getting-started">
  <a class="anchor inpage" href="#getting-started">##</a>Getting Started</h2>
<h3 id="have-a-try">
  <a class="anchor inpage" href="#have-a-try">###</a>Have a try</h3>
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>$ awk -F: <span style="color:#e6db74">&#39;{print $1, $NF}&#39;</span> /etc/passwd</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><table>
  <thead>
      <tr>
          <th>-</th>
          <th>-</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>-F:</code></td>
          <td>Colon as a separator</td>
      </tr>
      <tr>
          <td><code>{...}</code></td>
          <td>Awk program</td>
      </tr>
      <tr>
          <td><code>print</code></td>
          <td>Prints the current record</td>
      </tr>
      <tr>
          <td><code>$1</code></td>
          <td>First field</td>
      </tr>
      <tr>
          <td><code>$NF</code></td>
          <td>Last field</td>
      </tr>
      <tr>
          <td><code>/etc/passwd</code></td>
          <td>Input data file</td>
      </tr>
  </tbody>
</table>
<h3 id="awk-program">
  <a class="anchor inpage" href="#awk-program">###</a>Awk program</h3>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">BEGIN          {&lt;initializations&gt;}
   &lt;pattern 1&gt; {&lt;program actions&gt;}
   &lt;pattern 2&gt; {&lt;program actions&gt;}
   ...
END            {&lt; final actions &gt;}</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h4 id="example">
  <a class="anchor inpage" href="#example">####</a>Example</h4>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk &#39;
    BEGIN { print &#34;\n&gt;&gt;&gt;Start&#34; }
    !/(login|shutdown)/ { print NR, $0 }
    END { print &#34;&lt;&lt;&lt;END\n&#34; }
&#39; /etc/passwd</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="variables">
  <a class="anchor inpage" href="#variables">###</a>Variables</h3>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span>          $1      $2/<span style="color:#66d9ef">$(</span>NF-1<span style="color:#66d9ef">)</span>    $3/$NF
</span></span><span style="display:flex;"><span>           ▼          ▼           ▼
</span></span><span style="display:flex;"><span>        ┌──────┬──────────────────┬───────┐
</span></span><span style="display:flex;"><span>$0/NR ▶ │  ID  │  WEBSITE         │  URI  │
</span></span><span style="display:flex;"><span>        ├──────┼──────────────────┼───────┤
</span></span><span style="display:flex;"><span>$0/NR ▶ │  <span style="color:#ae81ff">1</span>   │  cheatsheets.zip │  awk  │
</span></span><span style="display:flex;"><span>        ├──────┼──────────────────┼───────┤
</span></span><span style="display:flex;"><span>$0/NR ▶ │  <span style="color:#ae81ff">2</span>   │  google.com      │  <span style="color:#ae81ff">25</span>   │
</span></span><span style="display:flex;"><span>        └──────┴──────────────────┴───────┘</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang=""># First and last field
awk -F: &#39;{print $1,$NF}&#39; /etc/passwd

# With line number
awk -F: &#39;{print NR, $0}&#39; /etc/passwd

# Second last field
awk -F: &#39;{print $(NF-1)}&#39; /etc/passwd

# Custom string
awk -F: &#39;{print $1 &#34;=&#34; $6}&#39; /etc/passwd</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="awk-program-examples">
  <a class="anchor inpage" href="#awk-program-examples">###</a>Awk program examples</h3>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk &#39;BEGIN {print &#34;hello world&#34;}&#39;        # Prints &#34;hello world&#34;
awk -F: &#39;{print $1}&#39; /etc/passwd         # -F: Specify field separator

# /pattern/ Execute actions only for matched pattern
awk -F: &#39;/root/ {print $1}&#39; /etc/passwd

# BEGIN block is executed once at the start
awk -F: &#39;BEGIN { print &#34;uid&#34;} { print $1 }&#39; /etc/passwd

# END block is executed once at the end
awk -F: &#39;{print $1} END { print &#34;-done-&#34;}&#39; /etc/passwd</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="conditions">
  <a class="anchor inpage" href="#conditions">###</a>Conditions</h3>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk -F: &#39;$3&gt;30 {print $1}&#39; /etc/passwd</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="generate-1000-spaces">
  <a class="anchor inpage" href="#generate-1000-spaces">###</a>Generate 1000 spaces</h3>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk &#39;BEGIN{
    while (a&#43;&#43; &lt; 1000)
        s=s &#34; &#34;;
    print s
}&#39;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="arrays">
  <a class="anchor inpage" href="#arrays">###</a>Arrays</h3>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk &#39;BEGIN {
   fruits[&#34;mango&#34;] = &#34;yellow&#34;;
   fruits[&#34;orange&#34;] = &#34;orange&#34;
   for(fruit in fruits) {
     print &#34;The color of &#34; fruit &#34; is &#34; fruits[fruit]
   }
}&#39;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="functions">
  <a class="anchor inpage" href="#functions">###</a>Functions</h3>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang=""># =&gt; 5
awk &#39;BEGIN{print length(&#34;hello&#34;)}&#39;
# =&gt; HELLO
awk &#39;BEGIN{print toupper(&#34;hello&#34;)}&#39;
# =&gt; hel
awk &#39;BEGIN{print substr(&#34;hello&#34;, 1, 3)}&#39;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h2 id="awk-variables">
  <a class="anchor inpage" href="#awk-variables">##</a>Awk Variables</h2>
<h3 id="build-in-variables">
  <a class="anchor inpage" href="#build-in-variables">###</a>Build-in variables</h3>
<table>
  <thead>
      <tr>
          <th>-</th>
          <th>-</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>$0</code></td>
          <td>Whole line</td>
      </tr>
      <tr>
          <td><code>$1, $2...$NF</code></td>
          <td>First, second… last field</td>
      </tr>
      <tr>
          <td><code>NR</code></td>
          <td><code>N</code>umber of <code>R</code>ecords</td>
      </tr>
      <tr>
          <td><code>NF</code></td>
          <td><code>N</code>umber of <code>F</code>ields</td>
      </tr>
      <tr>
          <td><code>OFS</code></td>
          <td><code>O</code>utput <code>F</code>ield <code>S</code>eparator <br> <em>(default &quot; &ldquo;)</em></td>
      </tr>
      <tr>
          <td><code>FS</code></td>
          <td>input <code>F</code>ield <code>S</code>eparator <br> <em>(default &quot; &ldquo;)</em></td>
      </tr>
      <tr>
          <td><code>ORS</code></td>
          <td><code>O</code>utput <code>R</code>ecord <code>S</code>eparator <br> <em>(default &ldquo;\n&rdquo;)</em></td>
      </tr>
      <tr>
          <td><code>RS</code></td>
          <td>input <code>R</code>ecord <code>S</code>eparator <br> <em>(default &ldquo;\n&rdquo;)</em></td>
      </tr>
      <tr>
          <td><code>FILENAME</code></td>
          <td>Name of the file</td>
      </tr>
  </tbody>
</table>
<h3 id="expressions">
  <a class="anchor inpage" href="#expressions">###</a>Expressions</h3>
<table>
  <thead>
      <tr>
          <th>-</th>
          <th>-</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>$1 == &quot;root&quot;</code></td>
          <td>First field equals root</td>
      </tr>
      <tr>
          <td><code>{print $(NF-1)}</code></td>
          <td>Second last field</td>
      </tr>
      <tr>
          <td><code>NR!=1{print $0}</code></td>
          <td>From 2nd record</td>
      </tr>
      <tr>
          <td><code>NR &gt; 3</code></td>
          <td>From 4th record</td>
      </tr>
      <tr>
          <td><code>NR == 1</code></td>
          <td>First record</td>
      </tr>
      <tr>
          <td><code>END{print NR}</code></td>
          <td>Total records</td>
      </tr>
      <tr>
          <td><code>BEGIN{print OFMT}</code></td>
          <td>Output format</td>
      </tr>
      <tr>
          <td><code>{print NR, $0}</code></td>
          <td>Line number</td>
      </tr>
      <tr>
          <td><code>{print NR &quot;	&quot; $0}</code></td>
          <td>Line number (tab)</td>
      </tr>
      <tr>
          <td><code>{$1 = NR; print}</code></td>
          <td>Replace 1st field with line number</td>
      </tr>
      <tr>
          <td><code>$NF &gt; 4</code></td>
          <td>Last field &gt; 4</td>
      </tr>
      <tr>
          <td><code>NR % 2 == 0</code></td>
          <td>Even records</td>
      </tr>
      <tr>
          <td><code>NR==10, NR==20</code></td>
          <td>Records 10 to 20</td>
      </tr>
      <tr>
          <td><code>BEGIN{print ARGC}</code></td>
          <td>Total arguments</td>
      </tr>
      <tr>
          <td><code>ORS=NR%5?&quot;,&quot;:&quot;\n&quot;</code></td>
          <td>Concatenate records</td>
      </tr>
  </tbody>
</table>
<h3 id="examples">
  <a class="anchor inpage" href="#examples">###</a>Examples</h3>
<p>Print sum and average</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk -F: &#39;{sum &#43;= $3}
     END { print sum, sum/NR }
&#39; /etc/passwd</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Printing parameters</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk &#39;BEGIN {
    for (i = 1; i &lt; ARGC; i&#43;&#43;)
        print ARGV[i] }&#39; a b c</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Output field separator as a comma</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk &#39;BEGIN { FS=&#34;:&#34;;OFS=&#34;,&#34;}
    {print $1,$2,$3,$4}&#39; /etc/passwd</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Position of match</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk &#39;BEGIN {
    if (match(&#34;One Two Three&#34;, &#34;Tw&#34;))
        print RSTART }&#39;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Length of match</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk &#39;BEGIN {
    if (match(&#34;One Two Three&#34;, &#34;re&#34;))
        print RLENGTH }&#39;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="environment-variables">
  <a class="anchor inpage" href="#environment-variables">###</a>Environment Variables</h3>
<table>
  <thead>
      <tr>
          <th>-</th>
          <th>-</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>ARGC</code></td>
          <td>Number or arguments</td>
      </tr>
      <tr>
          <td><code>ARGV</code></td>
          <td>Array of arguments</td>
      </tr>
      <tr>
          <td><code>FNR</code></td>
          <td><code>F</code>ile <code>N</code>umber of <code>R</code>ecords</td>
      </tr>
      <tr>
          <td><code>OFMT</code></td>
          <td>Format for numbers <br> <em>(default &ldquo;%.6g&rdquo;)</em></td>
      </tr>
      <tr>
          <td><code>RSTART</code></td>
          <td>Location in the string</td>
      </tr>
      <tr>
          <td><code>RLENGTH</code></td>
          <td>Length of match</td>
      </tr>
      <tr>
          <td><code>SUBSEP</code></td>
          <td>Multi-dimensional array separator <br> <em>(default &ldquo;\034&rdquo;)</em></td>
      </tr>
      <tr>
          <td><code>ARGIND</code></td>
          <td>Argument Index</td>
      </tr>
  </tbody>
</table>
<h3 id="gnu-awk-only">
  <a class="anchor inpage" href="#gnu-awk-only">###</a>GNU awk only</h3>
<table>
  <thead>
      <tr>
          <th>-</th>
          <th>-</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>ENVIRON</code></td>
          <td>Environment variables</td>
      </tr>
      <tr>
          <td><code>IGNORECASE</code></td>
          <td>Ignore case</td>
      </tr>
      <tr>
          <td><code>CONVFMT</code></td>
          <td>Conversion format</td>
      </tr>
      <tr>
          <td><code>ERRNO</code></td>
          <td>System errors</td>
      </tr>
      <tr>
          <td><code>FIELDWIDTHS</code></td>
          <td>Fixed width fields</td>
      </tr>
  </tbody>
</table>
<h3 id="defining-variable">
  <a class="anchor inpage" href="#defining-variable">###</a>Defining variable</h3>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk -v var1=&#34;Hello&#34; -v var2=&#34;Wold&#34; &#39;
    END {print var1, var2}
&#39; &lt;/dev/null</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h4 id="use-shell-variables">
  <a class="anchor inpage" href="#use-shell-variables">####</a>Use shell variables</h4>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk -v varName=&#34;$PWD&#34; &#39;
    END {print varName}&#39; &lt;/dev/null</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h2 id="awk-operators">
  <a class="anchor inpage" href="#awk-operators">##</a>Awk Operators</h2>
<h3 id="operators">
  <a class="anchor inpage" href="#operators">###</a>Operators</h3>
<table>
  <thead>
      <tr>
          <th>-</th>
          <th>-</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>{print $1}</code></td>
          <td>First field</td>
      </tr>
      <tr>
          <td><code>$2 == &quot;foo&quot;</code></td>
          <td>Equals</td>
      </tr>
      <tr>
          <td><code>$2 != &quot;foo&quot;</code></td>
          <td>Not equals</td>
      </tr>
      <tr>
          <td><code>&quot;foo&quot; in array</code></td>
          <td>In array</td>
      </tr>
  </tbody>
</table>
<h4 id="regular-expression">
  <a class="anchor inpage" href="#regular-expression">####</a>Regular expression</h4>
<table>
  <thead>
      <tr>
          <th>-</th>
          <th>-</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>/regex/</code></td>
          <td>Line matches</td>
      </tr>
      <tr>
          <td><code>!/regex/</code></td>
          <td>Line not matches</td>
      </tr>
      <tr>
          <td><code>$1 ~ /regex/</code></td>
          <td>Field matches</td>
      </tr>
      <tr>
          <td><code>$1 !~ /regex/</code></td>
          <td>Field not matches</td>
      </tr>
  </tbody>
</table>
<h4 id="more-conditions">
  <a class="anchor inpage" href="#more-conditions">####</a>More conditions</h4>
<table>
  <thead>
      <tr>
          <th>-</th>
          <th>-</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>($2 &lt;= 4 || $3 &lt; 20)</code></td>
          <td>Or</td>
      </tr>
      <tr>
          <td><code>($1 == 4 &amp;&amp; $3 &lt; 20)</code></td>
          <td>And</td>
      </tr>
  </tbody>
</table>
<h3 id="operations">
  <a class="anchor inpage" href="#operations">###</a>Operations</h3>
<h4 id="arithmetic-operations">
  <a class="anchor inpage" href="#arithmetic-operations">####</a>Arithmetic operations</h4>
<ul>
<li><code>+</code></li>
<li><code>-</code></li>
<li><code>*</code></li>
<li><code>/</code></li>
<li><code>%</code></li>
<li><code>++</code></li>
<li><code>--</code></li>
</ul>
<h4 id="shorthand-assignments">
  <a class="anchor inpage" href="#shorthand-assignments">####</a>Shorthand assignments</h4>
<ul>
<li><code>+=</code></li>
<li><code>-=</code></li>
<li><code>*=</code></li>
<li><code>/=</code></li>
<li><code>%=</code></li>
</ul>
<h4 id="comparison-operators">
  <a class="anchor inpage" href="#comparison-operators">####</a>Comparison operators</h4>
<ul>
<li><code>==</code></li>
<li><code>!=</code></li>
<li><code>&lt;</code></li>
<li><code>&gt;</code></li>
<li><code>&lt;=</code></li>
<li><code>&gt;=</code></li>
</ul>
<h3 id="examples-1">
  <a class="anchor inpage" href="#examples-1">###</a>Examples</h3>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk &#39;BEGIN {
    if (&#34;foo&#34; ~ &#34;^fo&#43;$&#34;)
        print &#34;Fooey!&#34;;
}&#39;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h4 id="not-match">
  <a class="anchor inpage" href="#not-match">####</a>Not match</h4>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk &#39;BEGIN {
    if (&#34;boo&#34; !~ &#34;^fo&#43;$&#34;)
        print &#34;Boo!&#34;;
}&#39;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h4 id="if-in-array">
  <a class="anchor inpage" href="#if-in-array">####</a>if in array</h4>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk &#39;BEGIN {
    assoc[&#34;foo&#34;] = &#34;bar&#34;;
    assoc[&#34;bar&#34;] = &#34;baz&#34;;
    if (&#34;foo&#34; in assoc)
        print &#34;Fooey!&#34;;
}&#39;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h2 id="awk-functions">
  <a class="anchor inpage" href="#awk-functions">##</a>Awk Functions</h2>
<h3 id="common-functions">
  <a class="anchor inpage" href="#common-functions">###</a>Common functions</h3>
<table>
  <thead>
      <tr>
          <th>Function</th>
          <th>Description</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>index(s,t)</code></td>
          <td>Position in string s where string t occurs, 0 if not found</td>
      </tr>
      <tr>
          <td><code>length(s)</code></td>
          <td>Length of string s (or $0 if no arg)</td>
      </tr>
      <tr>
          <td><code>rand</code></td>
          <td>Random number between 0 and 1</td>
      </tr>
      <tr>
          <td><code>substr(s,index,len)</code></td>
          <td>Return len-char substring of s that begins at index (counted from 1)</td>
      </tr>
      <tr>
          <td><code>srand</code></td>
          <td>Set seed for rand and return previous seed</td>
      </tr>
      <tr>
          <td><code>int(x)</code></td>
          <td>Truncate x to integer value</td>
      </tr>
      <tr>
          <td><code>split(s,a,fs)</code></td>
          <td>Split string s into array a split by fs, returning length of a</td>
      </tr>
      <tr>
          <td><code>match(s,r)</code></td>
          <td>Position in string s where regex r occurs, or 0 if not found</td>
      </tr>
      <tr>
          <td><code>sub(r,t,s)</code></td>
          <td>Substitute t for first occurrence of regex r in string s (or $0 if s not given)</td>
      </tr>
      <tr>
          <td><code>gsub(r,t,s)</code></td>
          <td>Substitute t for all occurrences of regex r in string s</td>
      </tr>
      <tr>
          <td><code>system(cmd)</code></td>
          <td>Execute cmd and return exit status</td>
      </tr>
      <tr>
          <td><code>tolower(s)</code></td>
          <td>String s to lowercase</td>
      </tr>
      <tr>
          <td><code>toupper(s)</code></td>
          <td>String s to uppercase</td>
      </tr>
      <tr>
          <td><code>getline</code></td>
          <td>Set $0 to next input record from current input file.</td>
      </tr>
  </tbody>
</table>
<h3 id="user-defined-function">
  <a class="anchor inpage" href="#user-defined-function">###</a>User defined function</h3>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk &#39;
    # Returns minimum number
    function find_min(num1, num2){
       if (num1 &lt; num2)
       return num1
       return num2
    }
    # Returns maximum number
    function find_max(num1, num2){
       if (num1 &gt; num2)
       return num1
       return num2
    }
    # Main function
    function main(num1, num2){
       result = find_min(num1, num2)
       print &#34;Minimum =&#34;, result

       result = find_max(num1, num2)
       print &#34;Maximum =&#34;, result
    }
    # Script execution starts here
    BEGIN {
       main(10, 60)
    }
&#39;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h2 id="awk-arrays">
  <a class="anchor inpage" href="#awk-arrays">##</a>Awk Arrays</h2>
<h3 id="array-with-index">
  <a class="anchor inpage" href="#array-with-index">###</a>Array with index</h3>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk &#39;BEGIN {
    arr[0] = &#34;foo&#34;;
    arr[1] = &#34;bar&#34;;
    print(arr[0]); # =&gt; foo
    delete arr[0];
    print(arr[0]); # =&gt; &#34;&#34;
}&#39;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="array-with-key">
  <a class="anchor inpage" href="#array-with-key">###</a>Array with key</h3>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk &#39;BEGIN {
    assoc[&#34;foo&#34;] = &#34;bar&#34;;
    assoc[&#34;bar&#34;] = &#34;baz&#34;;
    print(&#34;baz&#34; in assoc); # =&gt; 0
    print(&#34;foo&#34; in assoc); # =&gt; 1
}&#39;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="array-with-split">
  <a class="anchor inpage" href="#array-with-split">###</a>Array with split</h3>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk &#39;BEGIN {
    split(&#34;foo:bar:baz&#34;, arr, &#34;:&#34;);
    for (key in arr)
        print arr[key];
}&#39;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="array-with-asort">
  <a class="anchor inpage" href="#array-with-asort">###</a>Array with asort</h3>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk &#39;BEGIN {
    arr[0] = 3
    arr[1] = 2
    arr[2] = 4
    n = asort(arr)
    for (i = 1; i &lt;= n ; i&#43;&#43;)
        print(arr[i])
}&#39;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="multi-dimensional">
  <a class="anchor inpage" href="#multi-dimensional">###</a>Multi-dimensional</h3>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk &#39;BEGIN {
    multidim[0,0] = &#34;foo&#34;;
    multidim[0,1] = &#34;bar&#34;;
    multidim[1,0] = &#34;baz&#34;;
    multidim[1,1] = &#34;boo&#34;;
}&#39;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="multi-dimensional-iteration">
  <a class="anchor inpage" href="#multi-dimensional-iteration">###</a>Multi-dimensional iteration</h3>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk &#39;BEGIN {
    array[1,2]=3;
    array[2,3]=5;
    for (comb in array) {
        split(comb,sep,SUBSEP);
        print sep[1], sep[2],
        array[sep[1],sep[2]]
    }
}&#39;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h2 id="awk-conditions">
  <a class="anchor inpage" href="#awk-conditions">##</a>Awk Conditions</h2>
<h3 id="if-else-statement">
  <a class="anchor inpage" href="#if-else-statement">###</a>if-else statement</h3>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk -v count=2 &#39;BEGIN {
    if (count == 1)
        print &#34;Yes&#34;;
    else
        print &#34;Huh?&#34;;
}&#39;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h4 id="ternary-operator">
  <a class="anchor inpage" href="#ternary-operator">####</a>Ternary operator</h4>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk -v count=2 &#39;BEGIN {
    print (count==1) ? &#34;Yes&#34; : &#34;Huh?&#34;;
}&#39;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="exists">
  <a class="anchor inpage" href="#exists">###</a>Exists</h3>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk &#39;BEGIN {
    assoc[&#34;foo&#34;] = &#34;bar&#34;;
    assoc[&#34;bar&#34;] = &#34;baz&#34;;
    if (&#34;foo&#34; in assoc)
        print &#34;Fooey!&#34;;
}&#39;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h4 id="not-exists">
  <a class="anchor inpage" href="#not-exists">####</a>Not exists</h4>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk &#39;BEGIN {
    assoc[&#34;foo&#34;] = &#34;bar&#34;;
    assoc[&#34;bar&#34;] = &#34;baz&#34;;
    if (&#34;Huh&#34; in assoc == 0 )
        print &#34;Huh!&#34;;
}&#39;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="switch">
  <a class="anchor inpage" href="#switch">###</a>switch</h3>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk -F: &#39;{
    switch (NR * 2 &#43; 1) {
        case 3:
        case &#34;11&#34;:
            print NR - 1
            break

        case /2[[:digit:]]&#43;/:
            print NR

        default:
            print NR &#43; 1

        case -1:
            print NR * -1
    }
}&#39; /etc/passwd</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h2 id="awk-loops">
  <a class="anchor inpage" href="#awk-loops">##</a>Awk Loops</h2>
<h3 id="fori">
  <a class="anchor inpage" href="#fori">###</a>for&hellip;i</h3>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk &#39;BEGIN {
    for (i = 0; i &lt; 10; i&#43;&#43;)
        print &#34;i=&#34; i;
}&#39;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h4 id="powers-of-two-between-1-and-100">
  <a class="anchor inpage" href="#powers-of-two-between-1-and-100">####</a>Powers of two between 1 and 100</h4>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk &#39;BEGIN {
    for (i = 1; i &lt;= 100; i *= 2)
        print i
}&#39;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="forin">
  <a class="anchor inpage" href="#forin">###</a>for&hellip;in</h3>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk &#39;BEGIN {
    assoc[&#34;key1&#34;] = &#34;val1&#34;
    assoc[&#34;key2&#34;] = &#34;val2&#34;
    for (key in assoc)
        print assoc[key];
}&#39;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h4 id="arguments">
  <a class="anchor inpage" href="#arguments">####</a>Arguments</h4>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk &#39;BEGIN {
    for (argnum in ARGV)
        print ARGV[argnum];
}&#39; a b c</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="examples-2">
  <a class="anchor inpage" href="#examples-2">###</a>Examples</h3>
<h4 id="reverse-records">
  <a class="anchor inpage" href="#reverse-records">####</a>Reverse records</h4>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk -F: &#39;{ x[NR] = $0 }
    END {
        for (i = NR; i &gt; 0; i--)
        print x[i]
    }
&#39; /etc/passwd</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h4 id="reverse-fields">
  <a class="anchor inpage" href="#reverse-fields">####</a>Reverse fields</h4>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk -F: &#39;{
    for (i = NF; i &gt; 0; i--)
        printf(&#34;%s &#34;,$i);
    print &#34;&#34;
}&#39; /etc/passwd</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h4 id="sum-by-record">
  <a class="anchor inpage" href="#sum-by-record">####</a>Sum by record</h4>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk -F: &#39;{
    s=0;
    for (i = 1; i &lt;= NF; i&#43;&#43;)
        s &#43;= $i;
    print s
}&#39; /etc/passwd</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h4 id="sum-whole-file">
  <a class="anchor inpage" href="#sum-whole-file">####</a>Sum whole file</h4>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk -F: &#39;
    {for (i = 1; i &lt;= NF; i&#43;&#43;)
        s &#43;= $i;
    };
    END{print s}
&#39; /etc/passwd</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="while">
  <a class="anchor inpage" href="#while">###</a>while</h3>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk &#39;BEGIN {
    while (a &lt; 10) {
        print &#34;- &#34; &#34; concatenation: &#34; a
        a&#43;&#43;;
    }
}&#39;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h4 id="dowhile">
  <a class="anchor inpage" href="#dowhile">####</a>do&hellip;while</h4>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk &#39;{
    i = 1
    do {
        print $0
        i&#43;&#43;
    } while (i &lt;= 5)
}&#39; /etc/passwd</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="break">
  <a class="anchor inpage" href="#break">###</a>Break</h3>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk &#39;BEGIN {
    break_num = 5
    for (i = 0; i &lt; 10; i&#43;&#43;) {
        print i
        if (i == break_num)
            break
    }
}&#39;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="continue">
  <a class="anchor inpage" href="#continue">###</a>Continue</h3>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk &#39;BEGIN {
    for (x = 0; x &lt;= 10; x&#43;&#43;) {
        if (x == 5 || x == 6)
            continue
        printf &#34;%d &#34;, x
    }
    print &#34;&#34;
}&#39;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h2 id="awk-formatted-printing">
  <a class="anchor inpage" href="#awk-formatted-printing">##</a>Awk Formatted Printing</h2>
<h3 id="usage">
  <a class="anchor inpage" href="#usage">###</a>Usage</h3>
<h4 id="right-align">
  <a class="anchor inpage" href="#right-align">####</a>Right align</h4>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk &#39;BEGIN{printf &#34;|%10s|\n&#34;, &#34;hello&#34;}&#39;

|     hello|</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h4 id="left-align">
  <a class="anchor inpage" href="#left-align">####</a>Left align</h4>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk &#39;BEGIN{printf &#34;|%-10s|\n&#34;, &#34;hello&#34;}&#39;

|hello     |</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="common-specifiers">
  <a class="anchor inpage" href="#common-specifiers">###</a>Common specifiers</h3>
<table>
  <thead>
      <tr>
          <th>Character</th>
          <th>Description</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>c</code></td>
          <td>ASCII character</td>
      </tr>
      <tr>
          <td><code>d</code></td>
          <td>Decimal integer</td>
      </tr>
      <tr>
          <td><code>e</code>, <code>E</code>, <code>f</code></td>
          <td>Floating-point format</td>
      </tr>
      <tr>
          <td><code>o</code></td>
          <td>Unsigned octal value</td>
      </tr>
      <tr>
          <td><code>s</code></td>
          <td>String</td>
      </tr>
      <tr>
          <td><code>%</code></td>
          <td>Literal %</td>
      </tr>
  </tbody>
</table>
<h3 id="space">
  <a class="anchor inpage" href="#space">###</a>Space</h3>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk -F: &#39;{
    printf &#34;%-10s %s\n&#34;, $1, $(NF-1)
}&#39; /etc/passwd | head -n 3</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Outputs</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>root       /root
</span></span><span style="display:flex;"><span>bin        /bin
</span></span><span style="display:flex;"><span>daemon     /sbin</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="header">
  <a class="anchor inpage" href="#header">###</a>Header</h3>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">awk -F: &#39;BEGIN {
    printf &#34;%-10s %s\n&#34;, &#34;User&#34;, &#34;Home&#34;
    printf &#34;%-10s %s\n&#34;, &#34;----&#34;,&#34;----&#34;}
    { printf &#34;%-10s %s\n&#34;, $1, $(NF-1) }
&#39; /etc/passwd | head -n 5</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Outputs</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">User       Home
----       ----
root       /root
bin        /bin
daemon     /sbin</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h2 id="miscellaneous">
  <a class="anchor inpage" href="#miscellaneous">##</a>Miscellaneous</h2>
<h3 id="regex-metacharacters">
  <a class="anchor inpage" href="#regex-metacharacters">###</a>Regex Metacharacters</h3>
<ul>
<li><code>\</code></li>
<li><code>^</code></li>
<li><code>$</code></li>
<li><code>.</code></li>
<li><code>[</code></li>
<li><code>]</code></li>
<li><code>|</code></li>
<li><code>(</code></li>
<li><code>)</code></li>
<li><code>*</code></li>
<li><code>+</code></li>
<li><code>?</code></li>
</ul>
<h3 id="escape-sequences">
  <a class="anchor inpage" href="#escape-sequences">###</a>Escape Sequences</h3>
<table>
  <thead>
      <tr>
          <th>-</th>
          <th>-</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>\b</code></td>
          <td>Backspace</td>
      </tr>
      <tr>
          <td><code>\f</code></td>
          <td>Form feed</td>
      </tr>
      <tr>
          <td><code>\n</code></td>
          <td>Newline (line feed)</td>
      </tr>
      <tr>
          <td><code>\r</code></td>
          <td>Carriage return</td>
      </tr>
      <tr>
          <td><code>\t</code></td>
          <td>Horizontal tab</td>
      </tr>
      <tr>
          <td><code>\v</code></td>
          <td>Vertical tab</td>
      </tr>
  </tbody>
</table>
<h3 id="run-script">
  <a class="anchor inpage" href="#run-script">###</a>Run script</h3>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ cat demo.awk
</span></span><span style="display:flex;"><span><span style="color:#75715e">#!/usr/bin/awk -f</span>
</span></span><span style="display:flex;"><span>BEGIN <span style="color:#f92672">{</span> x <span style="color:#f92672">=</span> <span style="color:#ae81ff">23</span> <span style="color:#f92672">}</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">{</span> x <span style="color:#f92672">+=</span> <span style="color:#ae81ff">2</span> <span style="color:#f92672">}</span>
</span></span><span style="display:flex;"><span>END   <span style="color:#f92672">{</span> print x <span style="color:#f92672">}</span>
</span></span><span style="display:flex;"><span>$ awk -f demo.awk /etc/passwd
</span></span><span style="display:flex;"><span><span style="color:#ae81ff">69</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h2 id="also-see">
  <a class="anchor inpage" href="#also-see">##</a>Also see</h2>
<ul>
<li>

<em>(www-zeuthen.desy.de)</em></li>
<li>
 <em>(gist.github.com)</em></li>
</ul>
]]></content:encoded></item><item><title>grep</title><link>https://hiraethecho.github.io/docs/dev/grep/</link><pubDate>Mon, 05 May 2025 00:00:00 +0000</pubDate><author>wyz2016zxc@outlook.com(Hiraeth)</author><guid>https://hiraethecho.github.io/docs/dev/grep/</guid><description>&lt;h2 id="grep"&gt;
&lt;a class="anchor inpage" href="#grep"&gt;##&lt;/a&gt;grep&lt;/h2&gt;
&lt;p&gt;ref:
&lt;/p&gt;
&lt;h2 id="count-occurrence--c"&gt;
&lt;a class="anchor inpage" href="#count-occurrence--c"&gt;##&lt;/a&gt;Count Occurrence: &lt;code&gt;-c&lt;/code&gt;&lt;/h2&gt;
&lt;details open&gt;
&lt;summary&gt;TEXT&lt;/summary&gt;&lt;pre
class="codeblock"
&gt;&lt;code class="language-" data-lang=""&gt;$ cat example.txt | grep -c good
2&lt;/code&gt;&lt;button onclick="copyCode(this)" class="copybtn"&gt;copy&lt;/button&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;script&gt;
function copyCode(btn) {
const code = btn.previousElementSibling.textContent.trim();
navigator.clipboard.writeText(code).then(() =&gt; {
btn.innerText = "copied";
setTimeout(() =&gt; (btn.innerText = "copy"), 2000);
});
}
&lt;/script&gt;&lt;h2 id="get-context--c"&gt;
&lt;a class="anchor inpage" href="#get-context--c"&gt;##&lt;/a&gt;Get Context: &lt;code&gt;-C&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Set &lt;code&gt;--context=0&lt;/code&gt; to print that line alone&lt;/p&gt;
&lt;details open&gt;
&lt;summary&gt;TEXT&lt;/summary&gt;&lt;pre
class="codeblock"
&gt;&lt;code class="language-" data-lang=""&gt;$ cat example.txt | grep --context=0 &amp;#34;good luck&amp;#34;
good luck&lt;/code&gt;&lt;button onclick="copyCode(this)" class="copybtn"&gt;copy&lt;/button&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;script&gt;
function copyCode(btn) {
const code = btn.previousElementSibling.textContent.trim();
navigator.clipboard.writeText(code).then(() =&gt; {
btn.innerText = "copied";
setTimeout(() =&gt; (btn.innerText = "copy"), 2000);
});
}
&lt;/script&gt;&lt;p&gt;Set &lt;code&gt;--context=1&lt;/code&gt; to print 1 line below and 1 line above&lt;/p&gt;</description></item><item><title>shell概览</title><link>https://hiraethecho.github.io/docs/linux/shell/</link><pubDate>Mon, 05 May 2025 00:00:00 +0000</pubDate><author>wyz2016zxc@outlook.com(Hiraeth)</author><guid>https://hiraethecho.github.io/docs/linux/shell/</guid><description>主要靠ai生成的shell基本知识手册</description><content:encoded><![CDATA[<h1 id="shell">
  <a class="anchor inpage" href="#shell">#</a>shell</h1>
<h2 id="intro">
  <a class="anchor inpage" href="#intro">##</a>intro</h2>
<p>A shell is a command-line interpreter that provides a user interface for interacting with the operating system. It allows users to execute commands, run scripts, and manage system processes. Popular shells include bash, zsh, and fish.</p>
<h3 id="history">
  <a class="anchor inpage" href="#history">###</a>history</h3>
<p>The shell originated in the early days of UNIX, providing users a way to interact with the operating system. The Bourne Shell (sh) was one of the earliest, followed by more advanced shells like Bash, Zsh, and Fish. Each new shell introduced features that improved usability, scripting, and customization for users and administrators.</p>
<h3 id="posix">
  <a class="anchor inpage" href="#posix">###</a>posix</h3>
<p>POSIX stands for &ldquo;Portable Operating System Interface.&rdquo; It is a set of standardized operating system interfaces and shell command standards, maintained by the IEEE. POSIX ensures compatibility between Unix-like operating systems by defining common APIs, command-line utilities, and scripting interfaces.</p>
<p>In the context of shells, POSIX compliance ensures that shell scripts and commands written for one POSIX-compliant shell will work on another, regardless of the underlying operating system. For example, the <code>sh</code> shell is often used as a reference implementation for POSIX-compliant scripting. However, advanced shells like Bash and Zsh often extend POSIX standards with additional features and functionalities.</p>
<p>Key aspects of POSIX include:</p>
<ol>
<li><strong>Shell Command Language</strong>: Specifies syntax and utilities for scripting.</li>
<li><strong>System Interfaces</strong>: Defines APIs for file system operations, process control, and more.</li>
<li><strong>Utility Programs</strong>: Standardizes common tools like <code>grep</code>, <code>awk</code>, and <code>sed</code>.</li>
</ol>
<p>POSIX plays a critical role in ensuring interoperability and portability across different Unix-based systems, making it a cornerstone of modern shell environments.</p>
<h2 id="start-a-shell">
  <a class="anchor inpage" href="#start-a-shell">##</a>Start a shell</h2>
<p>There are three main cases that start a shell: login, interact, and in the shell scripts.</p>
<p>Linux starts a shell in the following situations:</p>
<ol>
<li><strong>Login Shell</strong>: Automatically invoked when a user logs in via TTY, SSH, or terminal emulator.</li>
<li><strong>Interactive Shell</strong>: When a user opens a new terminal window or manually starts a shell.</li>
<li><strong>Shell in Scripts</strong>: When a script containing a shebang (e.g., <code>#!/bin/bash</code>) is executed, the specified shell is started.</li>
</ol>
<p>there are also other cases, like ssh, getty, rescure mode etc</p>
<h3 id="login-shell">
  <a class="anchor inpage" href="#login-shell">###</a>login shell</h3>
<p>A shell starts automatically when you log in through a TTY, SSH, or terminal emulator. You can also start a shell manually by running its executable (e.g., bash, zsh, fish) from an existing shell or script. Shells start when prompted by the operating system or when explicitly invoked.</p>
<h3 id="interact-shell">
  <a class="anchor inpage" href="#interact-shell">###</a>interact shell</h3>
<p>After login, starting a new non-login shell (like opening a new terminal window) usually loads only the interactive shell configuration file (<code>~/.bashrc</code> for Bash, <code>~/.zshrc</code> for Zsh`). Environment variables and settings exported in the login shell are inherited by the new shell, unless overridden in the new shell&rsquo;s config file.</p>
<p>You can start most shells without loading configuration files by passing specific flags. For example, Bash: <code>bash --noprofile --norc</code>; Zsh: <code>zsh -f</code>. This launches the shell in a minimal state, ignoring personal and system-wide configuration files.</p>
<p>To start a shell as a different user, use the <code>su - username</code> or <code>sudo -i -u username</code> commands. The login shell for the specified user will be started, and it will load that user&rsquo;s configuration files (such as those in their home directory). Controlling which files are loaded depends on the shell and options passed; for example, you can use <code>bash --noprofile --norc</code> after switching users to avoid loading configs.</p>
<p>When starting a new shell with a different user, to avoid inheriting unwanted configuration, use options that bypass user config files (e.g. for Bash: <code>bash --noprofile --norc</code>; for Zsh: <code>zsh -f</code>). If you want to inherit configurations from the parent shell, you can manually export the desired environment variables before starting the new shell, or source config files as needed.</p>
<p>By default, when a new shell is started, the present working directory (PWD) is inherited from the parent process (the shell or terminal that launched it). If a shell is started during login (for example, via TTY or SSH), the default directory is usually the user&rsquo;s home directory (<code>$HOME</code>).</p>
<h3 id="shell-in-de">
  <a class="anchor inpage" href="#shell-in-de">###</a>shell in DE</h3>
<p>A special case is starting a shell in a DE (Desktop Environment).</p>
<p>Launcher programs like dmenu or rofi typically use the shell specified in the <code>SHELL</code> environment variable of the running user. If <code>SHELL</code> is not set, they may default to <code>/bin/sh</code> or whatever is configured in <code>/etc/passwd</code> for the user.</p>
<p>The default working directory (PWD) for a shell launched by a program like dmenu or rofi is typically the user&rsquo;s home directory (<code>$HOME</code>). However, this can be changed by the launcher or by the environment from which the launcher itself was started.</p>
<h3 id="shell-in-script">
  <a class="anchor inpage" href="#shell-in-script">###</a>shell in script</h3>
<p>Yes, when running a shell within a script (using shebang like <code>#!/bin/bash</code> or <code>#!/bin/zsh</code>), the script may behave differently depending on the shell used. Some shells have distinct syntax, built-ins, or environment handling. Scripts can also use subshells to isolate environments, and you can explicitly invoke subshells with commands like <code>(command)</code> or by calling another shell executable within the script.</p>
<p>When a shell is used in a script, it uses the environment variables defined in the parent shell or operating system environment where the script is executed. These may include system-wide variables (e.g., PATH, HOME) and user-defined variables from configuration files (e.g., ~/.bashrc, ~/.zshrc). The script can also define its own environment variables, which will only persist during the script&rsquo;s execution. Additionally, the shell may load configuration files specific to the shell being used, depending on whether the script is executed in a login or non-login context.</p>
<p>For example:</p>
<ul>
<li>A script that starts with <code>#!/bin/bash</code> as the shebang will inherit environment variables from the parent Bash shell.</li>
<li>If the script explicitly sources configuration files (e.g., <code>source ~/.bashrc</code>), it may load additional variables or settings.</li>
<li>Subshells started within the script can have isolated environments, which can either inherit variables or define new ones for their scope.</li>
</ul>
<p>To inspect or modify the environment variables in a script, commands like <code>export</code>, <code>printenv</code>, or <code>env</code> can be used.</p>
<p>Keep in mind that some shells have distinct syntax and behaviors concerning environment variables, so the choice of shell can influence the script&rsquo;s behavior.</p>
<p>To avoid unintended configurations, you can start the shell with options to bypass configuration files or explicitly define the environment variables needed by the script.</p>
<p>Example:</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span><span style="color:#75715e">#!/bin/bash --noprofile --norc
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>export MY_VARIABLE<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;value&#34;</span>
</span></span><span style="display:flex;"><span>echo <span style="color:#e6db74">&#34;Current PATH: </span>$PATH<span style="color:#e6db74">&#34;</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h2 id="configuration">
  <a class="anchor inpage" href="#configuration">##</a>configuration</h2>
<h3 id="set-shell">
  <a class="anchor inpage" href="#set-shell">###</a>set shell</h3>
<p>To change the default shell for a user, use the command:</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>chsh -s /path/to/shell</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>For example, to set Zsh as the default shell:</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>chsh -s <span style="color:#66d9ef">$(</span>which zsh<span style="color:#66d9ef">)</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="configuration-files">
  <a class="anchor inpage" href="#configuration-files">###</a>configuration files</h3>
<p>zsh</p>
<table>
  <thead>
      <tr>
          <th>Shell Type</th>
          <th>System Configurations</th>
          <th>User Configurations</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Login Shell</td>
          <td><code>/etc/zprofile</code>, <code>/etc/zlogin</code></td>
          <td><code>~/.zprofile</code>, <code>~/.zlogin</code></td>
      </tr>
      <tr>
          <td>Interactive Shell</td>
          <td><code>/etc/zshrc</code></td>
          <td><code>~/.zshrc</code></td>
      </tr>
      <tr>
          <td>Shell in a Script</td>
          <td><code>/etc/zshenv</code></td>
          <td><code>~/.zshenv</code></td>
      </tr>
  </tbody>
</table>
<p>bash</p>
<table>
  <thead>
      <tr>
          <th>Shell Type</th>
          <th>System Configurations</th>
          <th>User Configurations</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Login Shell</td>
          <td><code>/etc/profile</code></td>
          <td><code>~/.bash_profile</code>, <code>~/.bash_login</code>, <code>~/.profile</code></td>
      </tr>
      <tr>
          <td>Interactive Shell</td>
          <td><code>/etc/bash.bashrc</code></td>
          <td><code>~/.bashrc</code></td>
      </tr>
      <tr>
          <td>Shell in a Script</td>
          <td>None (scripts do not load config files)</td>
          <td>None</td>
      </tr>
  </tbody>
</table>
<h3 id="syntax">
  <a class="anchor inpage" href="#syntax">###</a>syntax</h3>
<p>Zsh Configuration Files:</p>
<ol>
<li>
<p><strong>Setting Environment Variables</strong>:</p>
<details open>
    <summary>zsh</summary><pre
        class="chroma codeblock"
      ><code class="language-zsh" data-lang="zsh"
          ><span style="display:flex;"><span>export PATH<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;</span>$PATH<span style="color:#e6db74">:/new/path&#34;</span>
</span></span><span style="display:flex;"><span>export EDITOR<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;vim&#34;</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
<li>
<p><strong>Defining Aliases</strong>:</p>
<details open>
    <summary>zsh</summary><pre
        class="chroma codeblock"
      ><code class="language-zsh" data-lang="zsh"
          ><span style="display:flex;"><span>alias ll<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;ls -la&#34;</span>
</span></span><span style="display:flex;"><span>alias gs<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;git status&#34;</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
<li>
<p><strong>Creating Functions</strong>:</p>
<details open>
    <summary>zsh</summary><pre
        class="chroma codeblock"
      ><code class="language-zsh" data-lang="zsh"
          ><span style="display:flex;"><span><span style="color:#66d9ef">function</span> greet<span style="color:#f92672">()</span> <span style="color:#f92672">{</span>
</span></span><span style="display:flex;"><span>    echo <span style="color:#e6db74">&#34;Hello, </span>$1<span style="color:#e6db74">!&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">}</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
<li>
<p><strong>Sourcing Other Files</strong>:</p>
<details open>
    <summary>zsh</summary><pre
        class="chroma codeblock"
      ><code class="language-zsh" data-lang="zsh"
          ><span style="display:flex;"><span>source ~/.zshrc</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
</ol>
<p>Bash Configuration Files:</p>
<ol>
<li>
<p><strong>Setting Environment Variables</strong>:</p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span>export PATH<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;</span>$PATH<span style="color:#e6db74">:/new/path&#34;</span>
</span></span><span style="display:flex;"><span>export EDITOR<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;vim&#34;</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
<li>
<p><strong>Defining Aliases</strong>:</p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span>alias ll<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;ls -la&#34;</span>
</span></span><span style="display:flex;"><span>alias gs<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;git status&#34;</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
<li>
<p><strong>Creating Functions</strong>:</p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span>greet<span style="color:#f92672">()</span> <span style="color:#f92672">{</span>
</span></span><span style="display:flex;"><span>    echo <span style="color:#e6db74">&#34;Hello, </span>$1<span style="color:#e6db74">!&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">}</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
<li>
<p><strong>Sourcing Other Files</strong>:</p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span>source ~/.bashrc</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
</ol>
<h2 id="shells">
  <a class="anchor inpage" href="#shells">##</a>shells</h2>
<p>Commonly used shells include:</p>
<ul>
<li>Bash (Bourne Again SHell): Default on many Linux systems</li>
<li>Zsh (Z Shell): Known for advanced features and customization</li>
<li>Fish (Friendly Interactive Shell): User-friendly and interactive</li>
<li>sh (Bourne Shell): The original UNIX shell</li>
<li>tcsh/csh: C Shell and its enhanced version</li>
</ul>
<table>
  <thead>
      <tr>
          <th>Shell</th>
          <th>Pros</th>
          <th>Cons</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Bash</td>
          <td>Widely supported, strong scripting capabilities</td>
          <td>Less modern interactive features</td>
      </tr>
      <tr>
          <td>Zsh</td>
          <td>Powerful completion, interactive features, customization</td>
          <td>Slightly heavier than Bash</td>
      </tr>
      <tr>
          <td>Fish</td>
          <td>User-friendly syntax and autocompletion</td>
          <td>Less POSIX-compatible for scripting</td>
      </tr>
      <tr>
          <td>sh</td>
          <td>Minimal and portable</td>
          <td>Limited interactivity and scripting features</td>
      </tr>
      <tr>
          <td>tcsh/csh</td>
          <td>C-like syntax, good for some users</td>
          <td>Less common, some scripting limitations</td>
      </tr>
  </tbody>
</table>
]]></content:encoded></item><item><title>sed cheatsheet</title><link>https://hiraethecho.github.io/docs/dev/sed/</link><pubDate>Thu, 01 May 2025 00:00:00 +0000</pubDate><author>wyz2016zxc@outlook.com(Hiraeth)</author><guid>https://hiraethecho.github.io/docs/dev/sed/</guid><description>&lt;h1 id="sed"&gt;
&lt;a class="anchor inpage" href="#sed"&gt;#&lt;/a&gt;sed&lt;/h1&gt;
&lt;h2 id="tldr"&gt;
&lt;a class="anchor inpage" href="#tldr"&gt;##&lt;/a&gt;tldr&lt;/h2&gt;
&lt;details open&gt;
&lt;summary&gt;sh&lt;/summary&gt;&lt;pre
class="chroma codeblock"
&gt;&lt;code class="language-sh" data-lang="sh"
&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sed -i &lt;span style="color:#e6db74"&gt;&amp;#34;[range]s/[patern]/[replacement]/[options]&amp;#34;&lt;/span&gt; file_*
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sed -i &lt;span style="color:#e6db74"&gt;&amp;#34;2,5s|[patern]|[replacement]|[options]&amp;#34;&lt;/span&gt; file_*&lt;/span&gt;&lt;/span&gt;&lt;/code
&gt;&lt;button onclick="copyCode(this)" class="copybtn"&gt;copy&lt;/button&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;script&gt;
function copyCode(btn) {
const code = btn.previousElementSibling.textContent.trim();
navigator.clipboard.writeText(code).then(() =&gt; {
btn.innerText = "copied";
setTimeout(() =&gt; (btn.innerText = "copy"), 2000);
});
}
&lt;/script&gt;&lt;h3 id="search-for-text"&gt;
&lt;a class="anchor inpage" href="#search-for-text"&gt;###&lt;/a&gt;Search for text&lt;/h3&gt;
&lt;p&gt;Search for a string and only print the lines that were matched&lt;/p&gt;
&lt;details open&gt;
&lt;summary&gt;sh&lt;/summary&gt;&lt;pre
class="chroma codeblock"
&gt;&lt;code class="language-sh" data-lang="sh"
&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ sed -n &lt;span style="color:#e6db74"&gt;&amp;#39;/hello/p&amp;#39;&lt;/span&gt; file.txt&lt;/span&gt;&lt;/span&gt;&lt;/code
&gt;&lt;button onclick="copyCode(this)" class="copybtn"&gt;copy&lt;/button&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;script&gt;
function copyCode(btn) {
const code = btn.previousElementSibling.textContent.trim();
navigator.clipboard.writeText(code).then(() =&gt; {
btn.innerText = "copied";
setTimeout(() =&gt; (btn.innerText = "copy"), 2000);
});
}
&lt;/script&gt;&lt;p&gt;Case insensitive search&lt;/p&gt;</description><content:encoded><![CDATA[<h1 id="sed">
  <a class="anchor inpage" href="#sed">#</a>sed</h1>
<h2 id="tldr">
  <a class="anchor inpage" href="#tldr">##</a>tldr</h2>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>sed -i <span style="color:#e6db74">&#34;[range]s/[patern]/[replacement]/[options]&#34;</span> file_*
</span></span><span style="display:flex;"><span>sed -i <span style="color:#e6db74">&#34;2,5s|[patern]|[replacement]|[options]&#34;</span> file_*</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="search-for-text">
  <a class="anchor inpage" href="#search-for-text">###</a>Search for text</h3>
<p>Search for a string and only print the lines that were matched</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ sed -n <span style="color:#e6db74">&#39;/hello/p&#39;</span> file.txt</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Case insensitive search</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ sed -n <span style="color:#e6db74">&#39;/hello/Ip&#39;</span> file.txt</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="sed-usage">
  <a class="anchor inpage" href="#sed-usage">###</a>Sed Usage</h3>
<p>Syntax</p>
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>$ sed <span style="color:#f92672">[</span>options<span style="color:#f92672">]</span> command <span style="color:#f92672">[</span>input-file<span style="color:#f92672">]</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>With pipeline</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ cat report.txt | sed <span style="color:#e6db74">&#39;s/Nick/John/g&#39;</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ echo <span style="color:#e6db74">&#39;123abc&#39;</span> | sed <span style="color:#e6db74">&#39;s/[0-9]+//g&#39;</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="option-examples">
  <a class="anchor inpage" href="#option-examples">###</a>Option Examples</h3>
<table>
  <thead>
      <tr>
          <th>Option</th>
          <th>Example</th>
          <th>Description</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>-i</code></td>
          <td>sed -ibak &rsquo;s/On/Off/&rsquo; php.ini</td>
          <td>Backup and modify input file directly</td>
      </tr>
      <tr>
          <td><code>-E</code></td>
          <td>sed -E &rsquo;s/[0-9]+//g&rsquo; input-file</td>
          <td>Use extended regular expressions</td>
      </tr>
      <tr>
          <td><code>-n</code></td>
          <td>sed -n &lsquo;3 p&rsquo; config.conf</td>
          <td>Suppress default pattern space printing</td>
      </tr>
      <tr>
          <td><code>-f</code></td>
          <td>sed -f script.sed config.conf</td>
          <td>Execute sed script file</td>
      </tr>
      <tr>
          <td><code>-e</code></td>
          <td>sed -e &lsquo;command1&rsquo; -e &lsquo;command2&rsquo; input-file</td>
          <td>Execute multiple sed commands</td>
      </tr>
  </tbody>
</table>
<h3 id="multiple-commands">
  <a class="anchor inpage" href="#multiple-commands">###</a>Multiple commands</h3>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ echo <span style="color:#e6db74">&#34;hello world&#34;</span> | sed -e <span style="color:#e6db74">&#39;s/h/H/g&#39;</span> -e <span style="color:#e6db74">&#39;s/w/W/g&#39;</span>
</span></span><span style="display:flex;"><span>Hello World</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Use <code>-e</code> to execute multiple sed commands</p>
<h3 id="sed-script">
  <a class="anchor inpage" href="#sed-script">###</a>Sed script</h3>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ echo <span style="color:#e6db74">&#39;s/h/H/g&#39;</span> &gt;&gt; hello.sed
</span></span><span style="display:flex;"><span>$ echo <span style="color:#e6db74">&#39;s/w/W/g&#39;</span> &gt;&gt; hello.sed
</span></span><span style="display:flex;"><span>$ echo <span style="color:#e6db74">&#34;hello world&#34;</span> | sed -f hello.sed
</span></span><span style="display:flex;"><span>Hello World</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Use <code>-f</code> to execute sed script file</p>
<h3 id="examples">
  <a class="anchor inpage" href="#examples">###</a>Examples</h3>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ sed <span style="color:#e6db74">&#39;s/old/new/g&#39;</span> file.txt
</span></span><span style="display:flex;"><span>$ sed <span style="color:#e6db74">&#39;s/old/new/g&#39;</span> file.txt &gt; new.txt
</span></span><span style="display:flex;"><span>$ sed <span style="color:#e6db74">&#39;s/old/new/g&#39;</span> -i file.txt
</span></span><span style="display:flex;"><span>$ sed <span style="color:#e6db74">&#39;s/old/new/g&#39;</span> -i.backup file.txt</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="sed-usage-1">
  <a class="anchor inpage" href="#sed-usage-1">###</a>Sed Usage</h3>
<p>Syntax</p>
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>$ sed <span style="color:#f92672">[</span>options<span style="color:#f92672">]</span> command <span style="color:#f92672">[</span>input-file<span style="color:#f92672">]</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>With pipeline</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ cat report.txt | sed <span style="color:#e6db74">&#39;s/Nick/John/g&#39;</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ echo <span style="color:#e6db74">&#39;123abc&#39;</span> | sed <span style="color:#e6db74">&#39;s/[0-9]+//g&#39;</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="option-examples-1">
  <a class="anchor inpage" href="#option-examples-1">###</a>Option Examples</h3>
<table>
  <thead>
      <tr>
          <th>Option</th>
          <th>Example</th>
          <th>Description</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>-i</code></td>
          <td>sed -ibak &rsquo;s/On/Off/&rsquo; php.ini</td>
          <td>Backup and modify input file directly</td>
      </tr>
      <tr>
          <td><code>-E</code></td>
          <td>sed -E &rsquo;s/[0-9]+//g&rsquo; input-file</td>
          <td>Use extended regular expressions</td>
      </tr>
      <tr>
          <td><code>-n</code></td>
          <td>sed -n &lsquo;3 p&rsquo; config.conf</td>
          <td>Suppress default pattern space printing</td>
      </tr>
      <tr>
          <td><code>-f</code></td>
          <td>sed -f script.sed config.conf</td>
          <td>Execute sed script file</td>
      </tr>
      <tr>
          <td><code>-e</code></td>
          <td>sed -e &lsquo;command1&rsquo; -e &lsquo;command2&rsquo; input-file</td>
          <td>Execute multiple sed commands</td>
      </tr>
  </tbody>
</table>
<h3 id="multiple-commands-1">
  <a class="anchor inpage" href="#multiple-commands-1">###</a>Multiple commands</h3>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ echo <span style="color:#e6db74">&#34;hello world&#34;</span> | sed -e <span style="color:#e6db74">&#39;s/h/H/g&#39;</span> -e <span style="color:#e6db74">&#39;s/w/W/g&#39;</span>
</span></span><span style="display:flex;"><span>Hello World</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Use <code>-e</code> to execute multiple sed commands</p>
<h3 id="sed-script-1">
  <a class="anchor inpage" href="#sed-script-1">###</a>Sed script</h3>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ echo <span style="color:#e6db74">&#39;s/h/H/g&#39;</span> &gt;&gt; hello.sed
</span></span><span style="display:flex;"><span>$ echo <span style="color:#e6db74">&#39;s/w/W/g&#39;</span> &gt;&gt; hello.sed
</span></span><span style="display:flex;"><span>$ echo <span style="color:#e6db74">&#34;hello world&#34;</span> | sed -f hello.sed
</span></span><span style="display:flex;"><span>Hello World</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Use <code>-f</code> to execute sed script file</p>
<h3 id="examples-1">
  <a class="anchor inpage" href="#examples-1">###</a>Examples</h3>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ sed <span style="color:#e6db74">&#39;s/old/new/g&#39;</span> file.txt
</span></span><span style="display:flex;"><span>$ sed <span style="color:#e6db74">&#39;s/old/new/g&#39;</span> file.txt &gt; new.txt
</span></span><span style="display:flex;"><span>$ sed <span style="color:#e6db74">&#39;s/old/new/g&#39;</span> -i file.txt
</span></span><span style="display:flex;"><span>$ sed <span style="color:#e6db74">&#39;s/old/new/g&#39;</span> -i.backup file.txt</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h2 id="sed-commands">
  <a class="anchor inpage" href="#sed-commands">##</a>Sed commands</h2>
<h3 id="commands">
  <a class="anchor inpage" href="#commands">###</a>Commands</h3>
<table>
  <thead>
      <tr>
          <th>Command</th>
          <th>Example</th>
          <th>Description</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>p</code></td>
          <td>sed -n &lsquo;1,4 p&rsquo; input.txt</td>
          <td>Print lines 1-4</td>
      </tr>
      <tr>
          <td><code>p</code></td>
          <td>sed -n -e &lsquo;1,4 p&rsquo; -e &lsquo;6,7 p&rsquo; input.txt</td>
          <td>Print lines 1-4 and 6-7</td>
      </tr>
      <tr>
          <td><code>d</code></td>
          <td>sed &lsquo;1,4 d&rsquo; input.txt</td>
          <td>Print lines except 1-4</td>
      </tr>
      <tr>
          <td><code>w</code></td>
          <td>sed -n &lsquo;1,4 w output.txt&rsquo; input.txt</td>
          <td>Write pattern space to file</td>
      </tr>
      <tr>
          <td><code>a</code></td>
          <td>sed &lsquo;2 a new-line&rsquo; input.txt</td>
          <td>Append line after</td>
      </tr>
      <tr>
          <td><code>i</code></td>
          <td>sed &lsquo;2 i new-line&rsquo; input.txt</td>
          <td>Insert line before</td>
      </tr>
  </tbody>
</table>
<h3 id="space-commands">
  <a class="anchor inpage" href="#space-commands">###</a>Space commands</h3>
<table>
  <thead>
      <tr>
          <th>Command</th>
          <th>Description</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>n</code></td>
          <td>Print pattern space, empty pattern space, and read next line</td>
      </tr>
      <tr>
          <td><code>x</code></td>
          <td>Swap pattern space with hold space</td>
      </tr>
      <tr>
          <td><code>h</code></td>
          <td>Copy pattern space to hold space</td>
      </tr>
      <tr>
          <td><code>H</code></td>
          <td>Append pattern space to hold space</td>
      </tr>
      <tr>
          <td><code>g</code></td>
          <td>Copy hold space to pattern space</td>
      </tr>
      <tr>
          <td><code>G</code></td>
          <td>Append hold space to pattern space</td>
      </tr>
  </tbody>
</table>
<h3 id="flags">
  <a class="anchor inpage" href="#flags">###</a>Flags</h3>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ sed <span style="color:#e6db74">&#39;s/old/new/[flags]&#39;</span> <span style="color:#f92672">[</span>input-file<span style="color:#f92672">]</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><hr>
<table>
  <thead>
      <tr>
          <th>Flag</th>
          <th>Description</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>g</code></td>
          <td>Global substitution</td>
      </tr>
      <tr>
          <td><code>1,2...</code></td>
          <td>Substitute the nth occurrence</td>
      </tr>
      <tr>
          <td><code>p</code></td>
          <td>Print only the substituted line</td>
      </tr>
      <tr>
          <td><code>w</code></td>
          <td>Write only the substituted line to a file</td>
      </tr>
      <tr>
          <td><code>I</code></td>
          <td>Ignore case while searching</td>
      </tr>
      <tr>
          <td><code>e</code></td>
          <td>Substitute and execute in the command line</td>
      </tr>
  </tbody>
</table>
<h3 id="loops-commands">
  <a class="anchor inpage" href="#loops-commands">###</a>Loops commands</h3>
<table>
  <thead>
      <tr>
          <th>Command</th>
          <th>Description</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>b label</code></td>
          <td>Branch to a label (for looping)</td>
      </tr>
      <tr>
          <td><code>t label</code></td>
          <td>Branch to a label only on successful substitution<br>(for looping)</td>
      </tr>
      <tr>
          <td><code>:label</code></td>
          <td>Label for the b and t commands (for looping)</td>
      </tr>
      <tr>
          <td><code>N</code></td>
          <td>Append next line to pattern space</td>
      </tr>
      <tr>
          <td><code>P</code></td>
          <td>Print 1st line in multi-line</td>
      </tr>
      <tr>
          <td><code>D</code></td>
          <td>Delete 1st line in multi-line</td>
      </tr>
  </tbody>
</table>
<h3 id="misc-flags">
  <a class="anchor inpage" href="#misc-flags">###</a>Misc Flags</h3>
<table>
  <thead>
      <tr>
          <th>Flag</th>
          <th>Description</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>/ | ^ @ ! #</code></td>
          <td>Substitution delimiter can be any character</td>
      </tr>
      <tr>
          <td><code>&amp;</code></td>
          <td>Gets the matched pattern</td>
      </tr>
      <tr>
          <td><code>( ) \1 \2 \3</code></td>
          <td>Group using <code>(</code> and <code>)</code>.<br>Use <code>\1</code>, <code>\2</code> in replacement to refer the group</td>
      </tr>
  </tbody>
</table>
<h2 id="sed-examples">
  <a class="anchor inpage" href="#sed-examples">##</a>Sed examples</h2>
<h3 id="replacing-text">
  <a class="anchor inpage" href="#replacing-text">###</a>Replacing text</h3>
<p>Replace all occurrences of a string</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ sed <span style="color:#e6db74">&#39;s/old/new/g&#39;</span> file.txt</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Replace only the nth occurrence of a string</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ sed <span style="color:#e6db74">&#39;s/old/new/2&#39;</span> file.txt</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Replace a string only on the 5th line</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ sed <span style="color:#e6db74">&#39;5 s/old/new/&#39;</span> file.txt</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Replace &ldquo;world&rdquo; with &ldquo;universe&rdquo; but only if the line begins with &ldquo;hello&rdquo;</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ sed <span style="color:#e6db74">&#39;/hello/s/world/universe/&#39;</span> file.txt</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Remove &ldquo;&quot; from the end of each line</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ sed <span style="color:#e6db74">&#39;s/\\$//&#39;</span> file.txt</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Remove all whitespace from beginning of each line</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ sed <span style="color:#e6db74">&#39;s/^\s*//&#39;</span> file.txt</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Remove comments. Even those that are at the end of a line</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ sed <span style="color:#e6db74">&#39;s/#.*$//&#39;</span> file.txt</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="search-for-text-1">
  <a class="anchor inpage" href="#search-for-text-1">###</a>Search for text</h3>
<p>Search for a string and only print the lines that were matched</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ sed -n <span style="color:#e6db74">&#39;/hello/p&#39;</span> file.txt</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Case insensitive search</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ sed -n <span style="color:#e6db74">&#39;/hello/Ip&#39;</span> file.txt</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Search for a string but only output lines that do not match</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ sed -n <span style="color:#e6db74">&#39;/hello/!p&#39;</span> file.txt</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="appending-lines">
  <a class="anchor inpage" href="#appending-lines">###</a>Appending lines</h3>
<p>Append line after line 2</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ sed <span style="color:#e6db74">&#39;2a Text after line 2&#39;</span> file.txt</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Append line at the end of the file</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ sed <span style="color:#e6db74">&#39;$a THE END!&#39;</span> file.txt</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Append line after every 3rd line starting from line 3</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ sed <span style="color:#e6db74">&#39;3~3a Some text&#39;</span> file.txt</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="numbering">
  <a class="anchor inpage" href="#numbering">###</a>Numbering</h3>
<p>Number line of a file (simple left alignment)</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ sed <span style="color:#f92672">=</span> file.txt | sed <span style="color:#e6db74">&#39;N;s/\n/\t/&#39;</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Number line of a file (number on left, right-aligned)</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ sed <span style="color:#f92672">=</span> file.txt | sed <span style="color:#e6db74">&#39;N; s/^/   /; s/ *\(.\{6,\}\)\n/\1  /&#39;</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Number line of file, but only print numbers if line is not blank</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ sed <span style="color:#e6db74">&#39;/./=&#39;</span> file.txt | sed <span style="color:#e6db74">&#39;/./N; s/\n/ /&#39;</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Count lines (emulates &ldquo;wc -l&rdquo;)</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ sed -n <span style="color:#e6db74">&#39;$=&#39;</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="prepending-lines">
  <a class="anchor inpage" href="#prepending-lines">###</a>Prepending lines</h3>
<p>Insert text before line 5</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ sed <span style="color:#e6db74">&#39;5i line number five&#39;</span> file.txt</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Insert &ldquo;Example: &quot; before each line that contains &ldquo;hello&rdquo;</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ sed <span style="color:#e6db74">&#39;/hello/i Example: &#39;</span> file.txt</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="deleting-lines">
  <a class="anchor inpage" href="#deleting-lines">###</a>Deleting lines</h3>
<p>Delete line 5-7 in file</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ sed <span style="color:#e6db74">&#39;5,7d&#39;</span> file.txt</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Delete every 2nd line starting with line 3</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ sed <span style="color:#e6db74">&#39;3~2d&#39;</span> file.txt</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Delete the last line in file</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ sed <span style="color:#e6db74">&#39;$d&#39;</span> file.txt</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Delete lines starting with &ldquo;Hello&rdquo;</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ sed <span style="color:#e6db74">&#39;/^Hello/d&#39;</span> file.txt</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Delete all empty lines</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ sed <span style="color:#e6db74">&#39;/^$/d&#39;</span> file.txt</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Delete lines starting with &ldquo;#&rdquo;</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ sed <span style="color:#e6db74">&#39;/^#/d&#39;</span> file.txt</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="file-spacing">
  <a class="anchor inpage" href="#file-spacing">###</a>File spacing</h3>
<p>Double space</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ sed G</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Delete all blank lines and double space</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ sed <span style="color:#e6db74">&#39;/^$/d;G&#39;</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Triple space a file</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ sed <span style="color:#e6db74">&#39;G;G&#39;</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Undo double-spacing</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ sed <span style="color:#e6db74">&#39;n;d&#39;</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Insert a blank line above line which matches &ldquo;regex&rdquo;</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ sed <span style="color:#e6db74">&#39;/regex/{x;p;x;}&#39;</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Insert a blank line below line which matches &ldquo;regex&rdquo;</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ sed <span style="color:#e6db74">&#39;/regex/G&#39;</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Insert a blank line around line which matches &ldquo;regex&rdquo;</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>$ sed <span style="color:#e6db74">&#39;/regex/{x;p;x;G;}&#39;</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h2 id="also-see">
  <a class="anchor inpage" href="#also-see">##</a>Also see</h2>
<ul>
<li>
 <em>(gist.github.com)</em>
<blockquote class="alert"><p>本文由 
 转码， 原文地址 

Sed is a stream editor, this sed cheat sheet contains sed commands and some common sed tricks.</p>
</blockquote></li>
</ul>
<h3 id="replacing-text-1">
  <a class="anchor inpage" href="#replacing-text-1">###</a>Replacing text</h3>
<p>Replace all occurrences of a string</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">$ sed &#39;s/old/new/g&#39; file.txt</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Replace only the nth occurrence of a string</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">$ sed &#39;s/old/new/2&#39; file.txt</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Replace replace a string only on the 5th line</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">$ sed &#39;5 s/old/new/&#39; file.txt</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Replace &ldquo;world&rdquo; with &ldquo;universe&rdquo; but only if the line begins with &ldquo;hello&rdquo;</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">$ sed &#39;/hello/s/world/universe/&#39; file.txt</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Remove &quot;&rdquo; from the end of each line</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">$ sed &#39;s/\\$//&#39; file.txt</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Remove all whitespace from beginning of each line</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">$ sed &#39;s/^\s*//&#39; file.txt</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Remove comments. Even those that are at the end of a line</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">$ sed &#39;s/#.*$//&#39; file.txt</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="search-for-text-2">
  <a class="anchor inpage" href="#search-for-text-2">###</a>Search for text</h3>
<p>Search for a string and only print the lines that were matched</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">$ sed -n &#39;/hello/p&#39; file.txt</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Case insensitive search</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">$ sed -n &#39;/hello/Ip&#39; file.txt</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Search for a string but only output lines that do not match</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">$ sed -n &#39;/hello/!p&#39; file.txt</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="appending-lines-1">
  <a class="anchor inpage" href="#appending-lines-1">###</a>Appending lines</h3>
<p>Append line after line 2</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">$ sed &#39;2a Text after line 2&#39; file.txt</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Append line at the end of the file</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">$ sed &#39;$a THE END!&#39; file.txt</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Append line after every 3rd line starting from line 3</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">$ sed &#39;3~3a Some text&#39; file.txt</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="numbering-1">
  <a class="anchor inpage" href="#numbering-1">###</a>Numbering</h3>
<p>Number line of a file (simple left alignment)</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">$ sed = file.txt | sed &#39;N;s/\n/\t/&#39;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Number line of a file (number on left, right-aligned)</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">$ sed = file.txt | sed &#39;N; s/^/   /; s/ *\(.\{6,\}\)\n/\1  /&#39;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Number line of file, but only print numbers if line is not blank</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">$ sed &#39;/./=&#39; file.txt | sed &#39;/./N; s/\n/ /&#39;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Count lines (emulates &ldquo;wc -l&rdquo;)</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">$ sed -n &#39;$=&#39;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="prepending-lines-1">
  <a class="anchor inpage" href="#prepending-lines-1">###</a>Prepending lines</h3>
<p>Insert text before line 5</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">$ sed &#39;5i line number five&#39; file.txt</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Insert &ldquo;Example:&rdquo; before each line that contains &ldquo;hello&rdquo;</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">$ sed &#39;/hello/i Example: &#39; file.txt</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="deleting-lines-1">
  <a class="anchor inpage" href="#deleting-lines-1">###</a>Deleting lines</h3>
<p>Delete line 5-7 in file</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">$ sed &#39;5,7d&#39; file.txt</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Delete every 2nd line starting with line 3</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">$ sed &#39;3~2d&#39; file.txt</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Delete the last line in file</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">$ sed &#39;$d&#39; file.txt</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Delete lines starting with &ldquo;Hello&rdquo;</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">$ sed &#39;/^Hello/d&#39; file.txt</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Delete all empty lines</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">$ sed &#39;/^$/d&#39; file.txt</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Delete lines starting with &ldquo;#&rdquo;</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">$ sed &#39;/^#/d&#39; file.txt</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="file-spacing-1">
  <a class="anchor inpage" href="#file-spacing-1">###</a>File spacing</h3>
<p>Double space</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">$ sed G</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Delete all blank lines and double space</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">$ sed &#39;/^$/d;G&#39;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Triple space a file</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">$ sed &#39;G;G&#39;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Undo double-spacing</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">$ sed &#39;n;d&#39;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Insert a blank line above line which matches &ldquo;regex&rdquo;</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">$ sed &#39;/regex/{x;p;x;}&#39;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Insert a blank line below line which matches &ldquo;regex&rdquo;</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">$ sed &#39;/regex/G&#39;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Insert a blank line around line which matches &ldquo;regex&rdquo;</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">$ sed &#39;/regex/{x;p;x;G;}&#39;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script>]]></content:encoded></item><item><title>Bash Scripts</title><link>https://hiraethecho.github.io/docs/linux/bash-scripts/</link><pubDate>Tue, 31 Dec 2024 00:00:00 +0000</pubDate><author>wyz2016zxc@outlook.com(Hiraeth)</author><guid>https://hiraethecho.github.io/docs/linux/bash-scripts/</guid><description>编写bash scripts的一些技巧</description><content:encoded><![CDATA[<h1 id="bash-scripts">
  <a class="anchor inpage" href="#bash-scripts">#</a>Bash Scripts</h1>
<h2 id="intro">
  <a class="anchor inpage" href="#intro">##</a>intro</h2>
<h3 id="run">
  <a class="anchor inpage" href="#run">###</a>run</h3>
<p>You can run the script in the following ways:</p>
<p><code>./hello_world.sh</code></p>
<p><code>bash hello_world.sh</code>.</p>
<h3 id="she-bang">
  <a class="anchor inpage" href="#she-bang">###</a>she-bang</h3>
<p>First line of shell Scripts usually is the <code>she-bang</code>:</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">#!/bin/sh</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Means using <code>/bin/sh</code> to run the script.</p>
<p>但是<code>/bin/sh</code>通常是符号链接，在不同机器上实际上是不同的shell，有时会有以外情况。所以建议写成</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">#!/bin/bash</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="注释">
  <a class="anchor inpage" href="#%e6%b3%a8%e9%87%8a">###</a>注释</h3>
<p>以 # 开头的行就是注释，会被解释器忽略。</p>
<p>多行注释可以使用以下格式：</p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span>:<span style="color:#e6db74">&lt;&lt;EOF
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">注释内容...
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">注释内容...
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">注释内容...
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">EOF</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>以上例子中，: 是一个空命令，用于执行后面的 Here 文档， &laquo;&lsquo;EOF&rsquo; 表示开启 Here 文档，COMMENT 是 Here 文档的标识符，在这两个标识符之间的内容都会被视为注释，不会被执行。</p>
<p>EOF 也可以使用其他符号:</p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>: <span style="color:#e6db74">&lt;&lt;&#39;COMMENT&#39;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">这是注释的部分。
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">可以有多行内容。
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">COMMENT</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>:&lt;&lt; <span style="color:#e6db74">&#39;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">注释内容...
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">注释内容...
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">注释内容...
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>:&lt;&lt;!
</span></span><span style="display:flex;"><span>注释内容...
</span></span><span style="display:flex;"><span>注释内容...
</span></span><span style="display:flex;"><span>注释内容...
</span></span><span style="display:flex;"><span>!</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h2 id="variables">
  <a class="anchor inpage" href="#variables">##</a>variables</h2>
<h3 id="define">
  <a class="anchor inpage" href="#define">###</a>define</h3>
<p>We can define a variable by using the syntax <code>variable_name=value</code>. To get the value of the variable, add <code>$</code> before the variable.</p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#75715e">#!/bin/bash
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#75715e"># A simple variable example</span>
</span></span><span style="display:flex;"><span>greeting<span style="color:#f92672">=</span>Hello
</span></span><span style="display:flex;"><span>name<span style="color:#f92672">=</span>Tux
</span></span><span style="display:flex;"><span>echo $greeting $name</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>注意，变量名和等号之间不能有空格</p>
<p>字符串：</p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span>my_string<span style="color:#f92672">=</span><span style="color:#960050;background-color:#1e0010">&#39;</span>Hello, World!my_string<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;Hello, World!&#34;</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">RUNOOB=&#34;www.runoob.com&#34;
LD_LIBRARY_PATH=&#34;/bin/&#34;
_var=&#34;123&#34;
var2=&#34;abc&#34;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#66d9ef">for</span> file in <span style="color:#ae81ff">\`</span> ls / etc <span style="color:#ae81ff">\`</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">for</span> file in $ <span style="color:#f92672">(</span>ls / etc<span style="color:#f92672">)</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>数组：</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">my_array=(1 2 3 4 5)</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>只读变量</p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#75715e">#!/bin/bash
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>
</span></span><span style="display:flex;"><span>myUrl<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;https://www.google.com&#34;</span>
</span></span><span style="display:flex;"><span>readonly myUrl
</span></span><span style="display:flex;"><span>myUrl<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;https://www.runoob.com&#34;</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>使用 unset 命令可以删除变量。语法：</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">unset variable_name</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="变量类型">
  <a class="anchor inpage" href="#%e5%8f%98%e9%87%8f%e7%b1%bb%e5%9e%8b">###</a>变量类型</h3>
<p><strong>字符串变量：</strong> 在 Shell中，变量通常被视为字符串。</p>
<p>你可以使用单引号 &rsquo; 或双引号 &quot; 来定义字符串，例如：</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">my_string=&#39;Hello, World!&#39;
my_string=&#34;Hello, World!&#34;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>单引号字符串的限制：</p>
<ul>
<li>单引号里的任何字符都会原样输出，单引号字符串中的变量是无效的；</li>
<li>单引号字符串中不能出现单独一个的单引号（对单引号使用转义符后也不行），但可成对出现，作为字符串拼接使用。</li>
</ul>
<p>双引号的优点：</p>
<ul>
<li>双引号里可以有变量</li>
<li>双引号里可以出现转义字符</li>
</ul>
<p>拼接字符串</p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span>your<span style="color:#ae81ff">\_</span>name <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;runoob&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ae81ff">\#</span> 使用双引号拼接
</span></span><span style="display:flex;"><span>greeting <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;hello, &#34;</span> $your<span style="color:#ae81ff">\_</span>name <span style="color:#e6db74">&#34;!&#34;</span>
</span></span><span style="display:flex;"><span>greeting<span style="color:#ae81ff">\_</span><span style="color:#ae81ff">1</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;hello, </span><span style="color:#e6db74">${</span>your<span style="color:#ae81ff">\_</span>name<span style="color:#e6db74">}</span><span style="color:#e6db74">!&#34;</span>
</span></span><span style="display:flex;"><span>echo $greeting $greeting<span style="color:#ae81ff">\_</span><span style="color:#ae81ff">1</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ae81ff">\#</span> 使用单引号拼接
</span></span><span style="display:flex;"><span>greeting<span style="color:#ae81ff">\_</span><span style="color:#ae81ff">2</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#39;hello, &#39;</span> $your<span style="color:#ae81ff">\_</span>name <span style="color:#e6db74">&#39;!&#39;</span>
</span></span><span style="display:flex;"><span>greeting<span style="color:#ae81ff">\_</span><span style="color:#ae81ff">3</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#39;hello, ${your\_name}!&#39;</span>
</span></span><span style="display:flex;"><span>echo $greeting<span style="color:#ae81ff">\_</span><span style="color:#ae81ff">2</span> $greeting<span style="color:#ae81ff">\_</span><span style="color:#ae81ff">3</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>输出结果为：</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">hello, runoob ! hello, runoob !
hello, runoob ! hello, ${your_name} !</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>获取字符串长度</p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span>string <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;abcd&#34;</span>
</span></span><span style="display:flex;"><span>echo <span style="color:#e6db74">${#</span>string<span style="color:#e6db74">}</span> <span style="color:#ae81ff">\#</span> 输出 <span style="color:#ae81ff">4</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="数组">
  <a class="anchor inpage" href="#%e6%95%b0%e7%bb%84">###</a>数组</h3>
<p>bash支持一维数组（不支持多维数组），并且没有限定数组的大小。</p>
<p>类似于 C 语言，数组元素的下标由 0 开始编号。获取数组中的元素要利用下标，下标可以是整数或算术表达式，其值应大于或等于 0。</p>
<p>在 Shell 中，用括号来表示数组，数组元素用&quot;空格&quot;符号分割开。定义数组的一般形式为：</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">数组名=(值1 值2 ... 值n)</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>例如：</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">array_name=(value0 value1 value2 value3)</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>或者</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">array_name=(
value0
value1
value2
value3
)</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>还可以单独定义数组的各个分量：</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">array_name[0]=value0
array_name[1]=value1
array_name[n]=valuen</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>可以不使用连续的下标，而且下标的范围没有限制。</p>
<p>读取数组元素值的一般格式是：</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">${数组名[下标]}</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>例如：</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">valuen=${array_name[n]}</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>使用 @ 符号可以获取数组中的所有元素，例如：</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">echo ${array_name[@]}</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>获取数组长度的方法与获取字符串长度的方法相同，例如：</p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#ae81ff">\#</span> 取得数组元素的个数
</span></span><span style="display:flex;"><span>length <span style="color:#f92672">=</span> <span style="color:#e6db74">${#</span>array<span style="color:#ae81ff">\_</span>name<span style="color:#ae81ff">\[</span>@<span style="color:#ae81ff">\]</span><span style="color:#e6db74">}</span>
</span></span><span style="display:flex;"><span><span style="color:#ae81ff">\#</span> 或者
</span></span><span style="display:flex;"><span>length <span style="color:#f92672">=</span> <span style="color:#e6db74">${#</span>array<span style="color:#ae81ff">\_</span>name<span style="color:#ae81ff">\[\*\]</span><span style="color:#e6db74">}</span>
</span></span><span style="display:flex;"><span><span style="color:#ae81ff">\#</span> 取得数组单个元素的长度
</span></span><span style="display:flex;"><span>length <span style="color:#f92672">=</span> <span style="color:#e6db74">${#</span>array<span style="color:#ae81ff">\_</span>name<span style="color:#ae81ff">\[</span>n<span style="color:#ae81ff">\]</span><span style="color:#e6db74">}</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="运算">
  <a class="anchor inpage" href="#%e8%bf%90%e7%ae%97">###</a>运算</h3>
<p>Arithmetic Expressions:</p>
<p>Below are the operators supported by bash for mathematical calculations:</p>
<table>
  <thead>
      <tr>
          <th>Operator</th>
          <th>Usage</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>+</td>
          <td>addition</td>
      </tr>
      <tr>
          <td>-</td>
          <td>subtraction</td>
      </tr>
      <tr>
          <td>*</td>
          <td>multiplication</td>
      </tr>
      <tr>
          <td>/</td>
          <td>division</td>
      </tr>
      <tr>
          <td>**</td>
          <td>exponentiation</td>
      </tr>
      <tr>
          <td>%</td>
          <td>modulus</td>
      </tr>
  </tbody>
</table>
<p>Numeric Comparison logical operators</p>
<p>Comparison is used to check if statements evaluate to <code>true</code> or <code>false</code>. We can use the below shown operators to compare two statements:</p>
<table>
  <thead>
      <tr>
          <th>Operation</th>
          <th>Syntax</th>
          <th>Explanation</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Equality</td>
          <td>num1 -eq num2</td>
          <td>is num1 equal to num2</td>
      </tr>
      <tr>
          <td>Greater than equal to</td>
          <td>num1 -ge num2</td>
          <td>is num1 greater than equal to num2</td>
      </tr>
      <tr>
          <td>Greater than</td>
          <td>num1 -gt num2</td>
          <td>is num1 greater than num2</td>
      </tr>
      <tr>
          <td>Less than equal to</td>
          <td>num1 -le num2</td>
          <td>is num1 less than equal to num2</td>
      </tr>
      <tr>
          <td>Less than</td>
          <td>num1 -lt num2</td>
          <td>is num1 less than num2</td>
      </tr>
      <tr>
          <td>Not Equal to</td>
          <td>num1 -ne num2</td>
          <td>is num1 not equal to num2</td>
      </tr>
  </tbody>
</table>
<h3 id="参数">
  <a class="anchor inpage" href="#%e5%8f%82%e6%95%b0">###</a>参数</h3>
<table>
  <thead>
      <tr>
          <th>名称</th>
          <th>含义</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>$#</td>
          <td>传给脚本的参数个数</td>
      </tr>
      <tr>
          <td>$0</td>
          <td>脚本本身的名字</td>
      </tr>
      <tr>
          <td>$1</td>
          <td>传递给该shell脚本的第一个参数</td>
      </tr>
      <tr>
          <td>$2</td>
          <td>传递给该shell脚本的第二个参数</td>
      </tr>
      <tr>
          <td>$@</td>
          <td>传给脚本的所有参数的列表</td>
      </tr>
      <tr>
          <td>$*</td>
          <td>以一个单字符串显示所有向脚本传递的参数，与位置变量不同，参数可超过9个</td>
      </tr>
      <tr>
          <td>$$</td>
          <td>脚本运行的当前进程ID号</td>
      </tr>
      <tr>
          <td>$?</td>
          <td>显示最后命令的退出状态，0表示没有错误，其他表示有错误</td>
      </tr>
  </tbody>
</table>
<p>假设执行 <code>./test.sh a b c</code> 这样一个命令，则可以使用下面的参数来获取一些值：</p>
<ul>
<li><code>$0</code><br>
对应 <em>./test.sh</em> 这个值。如果执行的是 <code>./work/test.sh</code> ， 则对应 <em>./work/test.sh</em> 这个值，而不是只返回文件名本身的部分。</li>
<li><code>$1</code><br>
会获取到 a，即 <code>$1</code> 对应传给脚本的第一个参数。</li>
<li><code>$2</code><br>
会获取到 b，即 <code>$2</code> 对应传给脚本的第二个参数。</li>
<li><code>$3</code><br>
会获取到 c，即 <code>$3</code> 对应传给脚本的第三个参数。 <code>$4</code> 、 <code>$5</code> 等参数的含义依此类推。</li>
<li><code>$#</code><br>
会获取到 3，对应传入脚本的参数个数，统计的参数不包括 <code>$0</code> 。</li>
<li><code>$@</code><br>
会获取到 &ldquo;a&rdquo; &ldquo;b&rdquo; &ldquo;c&rdquo;，也就是所有参数的列表，不包括 <code>$0</code> 。</li>
<li><code>$*</code><br>
也会获取到 &ldquo;a&rdquo; &ldquo;b&rdquo; &ldquo;c&rdquo;， 其值和 <code>$@</code> 相同。但 <code>&quot;$*&quot;</code> 和 <code>&quot;$@&quot;</code> 有所不同。<br>
<code>&quot;$*&quot;</code> 把所有参数合并成一个字符串，而 <code>&quot;$@&quot;</code> 会得到一个字符串参数数组。</li>
<li><code>$?</code><br>
可以获取到执行 <code>./test.sh a b c</code> 命令后的返回值。<br>
在执行一个前台命令后，可以立即用 <code>$?</code> 获取到该命令的返回值。<br>
该命令可以是系统自身的命令，可以是 shell 脚本，也可以是自定义的 bash 函数。</li>
</ul>
<p>当执行系统自身的命令时， <code>$?</code> 对应这个命令的返回值。<br>
当执行 shell 脚本时， <code>$?</code> 对应该脚本调用 <code>exit</code> 命令返回的值。如果没有主动调用 <code>exit</code> 命令，默认返回为 0。<br>
当执行自定义的 bash 函数时， <code>$?</code> 对应该函数调用 <code>return</code> 命令返回的值。如果没有主动调用 <code>return</code> 命令，默认返回为 0。</p>
<p>下面举例说明 <code>&quot;$*&quot;</code> 和 <code>&quot;$@&quot;</code> 的差异。假设有一个 <code>testparams.sh</code> 脚本，内容如下：</p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#75715e">#!/bin/bash
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">for</span> arg in <span style="color:#e6db74">&#34;</span>$*<span style="color:#e6db74">&#34;</span>; <span style="color:#66d9ef">do</span>
</span></span><span style="display:flex;"><span>    echo <span style="color:#e6db74">&#34;****:&#34;</span> $arg
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">done</span>
</span></span><span style="display:flex;"><span>echo --------------
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">for</span> arg in <span style="color:#e6db74">&#34;</span>$@<span style="color:#e6db74">&#34;</span>; <span style="color:#66d9ef">do</span>
</span></span><span style="display:flex;"><span>    echo <span style="color:#e6db74">&#34;@@@@:&#34;</span> $arg
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">done</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>这个脚本分别遍历 <code>&quot;$*&quot;</code> 和 <code>&quot;$@&quot;</code> 扩展后的内容，并打印出来。</p>
<p>执行 <code>./testparams.sh</code> 脚本，结果如下：</p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span>$ ./testparams.sh This is a test
</span></span><span style="display:flex;"><span>****: This is a test
</span></span><span style="display:flex;"><span>--------------
</span></span><span style="display:flex;"><span>@@@@: This
</span></span><span style="display:flex;"><span>@@@@: is
</span></span><span style="display:flex;"><span>@@@@: a
</span></span><span style="display:flex;"><span>@@@@: test</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>可以看到， <code>&quot;$*&quot;</code> 只产生一个字符串，for 循环只遍历一次。<br>
而 <code>&quot;$@&quot;</code> 产生了多个字符串，for 循环遍历多次，是一个字符串参数数组。</p>
<p><strong>注意</strong> ：如果传入的参数多于 9 个，则不能使用 <code>$10</code> 来引用第 10 个参数，而是要用 <code>${10}</code> 来引用。</p>
<p>即，需要用大括号 <code>{}</code> 把大于 9 的数字括起来。<br>
例如， <code>${10}</code> 表示获取第 10 个参数的值，写为 <code>$10</code> 获取不到第 10 个参数的值。<br>
实际上， <code>$10</code> 相当于 <code>${1}0</code> ，也就是先获取 <code>$1</code> 的值，后面再跟上 0。<br>
如果 <code>$1</code> 的值是 &ldquo;first&rdquo;，则 <code>$10</code> 的值是 &ldquo;first0&rdquo;。</p>
<p>在 bash 中，可以使用 <code>$#</code> 来获取传入的命令行或者传入函数的参数个数。<br>
要注意的是， <code>$#</code> 统计的参数个数不包括脚本自身名称或者函数名称。<br>
例如，执行 <code>./a.sh a b</code> ，则 <code>$#</code> 是 2，而不是 3。</p>
<h2 id="pairs">
  <a class="anchor inpage" href="#pairs">##</a>pairs</h2>
<p><code>{}</code>,<code>[]</code>,<code>()</code>,<code>``</code></p>
<h3 id="-花括号">
  <a class="anchor inpage" href="#-%e8%8a%b1%e6%8b%ac%e5%8f%b7">###</a>{} 花括号</h3>
<h4 id="常规用法">
  <a class="anchor inpage" href="#%e5%b8%b8%e8%a7%84%e7%94%a8%e6%b3%95">####</a>常规用法</h4>
<p>大括号拓展。(通配(globbing))将对大括号中的文件名做扩展。在大括号中，不允许有空白，除非这个空白被引用或转义。第一种：对大括号中的以逗号分割的文件列表进行拓展。如 touch {a,b}.txt 结果为a.txt b.txt。第二种：对大括号中以点点（..）分割的顺序文件列表起拓展作用，如：touch {a..d}.txt 结果为a.txt b.txt c.txt d.txt</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang=""># ls {ex1,ex2}.sh
ex1.sh  ex2.sh
# ls {ex{1..3},ex4}.sh
ex1.sh  ex2.sh  ex3.sh  ex4.sh
# ls {ex[1-3],ex4}.sh
ex1.sh  ex2.sh  ex3.sh  ex4.sh</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>代码块，又被称为内部组，这个结构事实上创建了一个匿名函数 。与小括号中的命令不同，大括号内的命令不会新开一个子shell运行，即脚本余下部分仍可使用括号内变量。括号内的命令间用分号隔开，最后一个也必须有分号。{}的第一个命令和左括号之间必须要有一个空格。</p>
<h4 id="几种特殊的替换结构">
  <a class="anchor inpage" href="#%e5%87%a0%e7%a7%8d%e7%89%b9%e6%ae%8a%e7%9a%84%e6%9b%bf%e6%8d%a2%e7%bb%93%e6%9e%84">####</a>几种特殊的替换结构</h4>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">${var:-string}
${var:&#43;string}
${var:=string}
${var:?string}</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><ol>
<li>
<p><code>${var:-string}</code>和<code>${var:=string}</code>:若变量var为空，则用在命令行中用string来替换<code>${var:-string}</code>，否则变量var不为空时，则用变量var的值来替换<code>${var:-string}</code>；对于<code>${var:=string}</code>的替换规则和<code>${var:-string}</code>是一样的，所不同之处是<code>${var:=string}</code>若var为空时，用string替换<code>${var:=string}</code>的同时，把string赋给变量var： <code>${var:=string}</code>很常用的一种用法是，判断某个变量是否赋值，没有的话则给它赋上一个默认值。</p>
</li>
<li>
<p><code>${var:+string}</code>的替换规则和上面的相反，即只有当var不是空的时候才替换成string，若var为空时则不替换或者说是替换成变量 var的值，即空值。(因为变量var此时为空，所以这两种说法是等价的)</p>
</li>
<li>
<p><code>${var:?string}</code>替换规则为：若变量var不为空，则用变量var的值来替换<code>${var:?string}</code>；若变量var为空，则把string输出到标准错误中，并从脚本中退出。我们可利用此特性来检查是否设置了变量的值。</p>
</li>
</ol>
<p>在上面这五种替换结构中string不一定是常值的，可用另外一个变量的值或是一种命令的输出。</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">default_name=&#34;Guest&#34;
unset name  # 确保 name 未定义

# 如果 name 为空，则使用 default_name 的值
echo &#34;Hello, ${name:-$default_name}&#34;  # 输出: Hello, Guest</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p><strong>四种模式匹配替换结构</strong></p>
<p>模式匹配记忆方法：</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang=""># 是去掉左边(在键盘上#在$之左边)
% 是去掉右边(在键盘上%在$之右边)</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p><code>#</code>和<code>%</code>中的单一符号是最小匹配，两个相同符号是最大匹配。</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">${var%pattern}
${var%%pattern
${var#pattern}
${var##pattern}</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><ul>
<li>第一种模式：<code>${variable%pattern}</code>，这种模式时，shell在variable中查找，看它是否一给的模式pattern结尾，如果是，就从命令行把variable中的内容去掉右边最短的匹配模式</li>
<li>第二种模式： <code>${variable%%pattern}</code>，这种模式时，shell在variable中查找，看它是否一给的模式pattern结尾，如果是，就从命令行把variable中的内容去掉右边最长的匹配模式</li>
<li>第三种模式：<code>${variable#pattern}</code> 这种模式时，shell在variable中查找，看它是否一给的模式pattern开始，如果是，就从命令行把variable中的内容去掉左边最短的匹配模式</li>
<li>第四种模式： <code>${variable##pattern}</code> 这种模式时，shell在variable中查找，看它是否一给的模式pattern结尾，如果是，就从命令行把variable中的内容去掉右边最长的匹配模式</li>
<li>这四种模式中都不会改变variable的值，其中，只有在pattern中使用了*匹配符号时，%和%%，#和##才有区别。结构中的pattern支持通配符，*表示零个或多个任意字符，?表示仅与一个任意字符匹配，\[...\]表示匹配中括号里面的字符，\[!...\]表示不匹配中括号里面的字符。</li>
</ul>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang=""># var=testcase
# echo $var
testcase
# echo ${var%s*e}
testca
# echo $var
testcase
# echo ${var%%s*e}
te
# echo ${var#?e}
stcase
# echo ${var##?e}
stcase
# echo ${var##*e}

# echo ${var##*s}
e
# echo ${var##test}
case</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h4 id="字符串提取和替换">
  <a class="anchor inpage" href="#%e5%ad%97%e7%ac%a6%e4%b8%b2%e6%8f%90%e5%8f%96%e5%92%8c%e6%9b%bf%e6%8d%a2">####</a>字符串提取和替换</h4>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">${var:num}
${var:num1:num2}
${var/pattern/pattern}
${var//pattern/pattern}</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><ul>
<li>第一种模式：<code>${var:num}</code>，这种模式时，shell在var中提取第num个字符到末尾的所有字符。若num为正数，从左边0处开始；若num为负数，从右边开始提取字串，但必须使用在冒号后面加空格或一个数字或整个num加上括号，如<code>${var: -2}</code>、<code>${var:1-3}</code>或<code>${var:(-2)}</code>。</li>
<li>第二种模式：<code>${var:num1:num2}</code>，num1是位置，num2是长度。表示从$var字符串的第$num1个位置开始提取长度为$num2的子串。不能为负数。</li>
<li>第三种模式：<code>${var/pattern/pattern}</code>表示将var字符串的第一个匹配的pattern替换为另一个pattern。</li>
<li>第四种模式：<code>${var//pattern/pattern}</code>表示将var字符串中的所有能匹配的pattern替换为另一个pattern。</li>
</ul>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">[root@centos ~]# var=/home/centos
[root@centos ~]# echo $var
/home/centos
[root@centos ~]# echo ${var:5}
/centos
[root@centos ~]# echo ${var: -6}
centos
[root@centos ~]# echo ${var:(-6)}
centos
[root@centos ~]# echo ${var:1:4}
home
[root@centos ~]# echo ${var/o/h}
/hhme/centos
[root@centos ~]# echo ${var//o/h}
/hhme/cenths</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><ul>
<li>
<p>${a} 变量a的值, 在不引起歧义的情况下可以省略大括号。</p>
</li>
<li>
<p>$(cmd) 命令替换，和`cmd`效果相同，结果为shell命令cmd的输，过某些Shell版本不支持$()形式的命令替换, 如tcsh。</p>
</li>
<li>
<p>$((expression)) 和`exprexpression`效果相同, 计算数学表达式exp的数值, 其中exp只要符合C语言的运算规则即可, 甚至三目运算符和逻辑表达式都可以计算。</p>
</li>
<li>
<p>单小括号，(cmd1;cmd2;cmd3) 新开一个子shell顺序执行命令cmd1,cmd2,cmd3, 各命令之间用分号隔开, 最后一个命令后可以没有分号。</p>
</li>
<li>
<p>单大括号，{ cmd1;cmd2;cmd3;} 在当前shell顺序执行命令cmd1,cmd2,cmd3, 各命令之间用分号隔开, 最后一个命令后必须有分号, 第一条命令和左括号之间必须用空格隔开。
对 {} 和 () 而言, 括号中的重定向符只影响该条命令， 而括号外的重定向符影响到括号中的所有命令。</p>
</li>
</ul>
<h3 id="heading">
  <a class="anchor inpage" href="#heading">###</a><code>[]</code></h3>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span>type <span style="color:#f92672">[</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">[</span> is a shell builtin</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>This means that &lsquo;[&rsquo; is actually a program, just like ls and other programs, so it must be surrounded by spaces.</p>
<ul>
<li>bash 的内部命令，[和test是等同的。如果我们不用绝对路径指明，通常我们用的都是bash自带的命令。if/test结构中的左中括号是调用test的命令标识，右中括号是关闭条件判断的。这个命令把它的参数作为比较表达式或者作为文件测试，并且根据比较的结果来返回一个退出状态码。if/test结构中并不是必须右中括号，但是新版的Bash中要求必须这样。</li>
<li>Test和[]中可用的比较运算符只有==和!=，两者都是用于字符串比较的，不可用于整数比较，整数比较只能使用-eq，-gt这种形式。无论是字符串比较还是整数比较都不支持大于号小于号。如果实在想用，对于字符串比较可以使用转义形式，如果比较&quot;ab&quot;和&quot;bc&quot;：\[ ab \\< bc \]，结果为真，也就是返回状态为0。\[ \]中的逻辑与和逻辑或使用-a 和-o 表示。</li>
<li>字符范围。用作正则表达式的一部分，描述一个匹配的字符范围。作为test用途的中括号内不能使用正则。</li>
<li>在一个array 结构的上下文中，中括号用来引用数组中每个元素的编号。</li>
</ul>
<h3 id="heading-1">
  <a class="anchor inpage" href="#heading-1">###</a><code>[[]]</code></h3>
<ul>
<li>\[\[是 bash 程序语言的关键字。并不是一个命令，\[\[ \]] 结构比\[ \]结构更加通用。在\[\[和\]]之间所有的字符都不会发生文件名扩展或者单词分割，但是会发生参数扩展和命令替换。</li>
<li>支持字符串的模式匹配，使用=~操作符时甚至支持shell的正则表达式。字符串比较时可以把右边的作为一个模式，而不仅仅是一个字符串，比如\[\[ hello == hell? \]]，结果为真。\[\[ \]] 中匹配字符串或通配符，不需要引号。</li>
<li>使用\[\[... \]]条件判断结构，而不是\[... \]，能够防止脚本中的许多逻辑错误。比如，&amp;&amp;、||、&lt;和&gt; 操作符能够正常存在于\[\[ \]]条件判断结构中，但是如果出现在\[ \]结构中的话，会报错。比如可以直接使用if \[\[ $a!= 1 && $a!= 2 \]], 如果不适用双括号, 则为if \[ $a -ne 1\] &amp;&amp; \[ $a!= 2 \]或者if \[ $a -ne 1 -a $a!= 2 \]。</li>
<li>bash把双中括号中的表达式看作一个单独的元素，并返回一个退出状态码。</li>
</ul>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#66d9ef">if</span> <span style="color:#f92672">(</span>$i&lt;5<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> <span style="color:#f92672">[</span> $i -lt <span style="color:#ae81ff">5</span> <span style="color:#f92672">]</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> <span style="color:#f92672">[</span> $a -ne <span style="color:#ae81ff">1</span> -a $a !<span style="color:#f92672">=</span> <span style="color:#ae81ff">2</span> <span style="color:#f92672">]</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> <span style="color:#f92672">[</span> $a -ne 1<span style="color:#f92672">]</span> <span style="color:#f92672">&amp;&amp;</span> <span style="color:#f92672">[</span> $a !<span style="color:#f92672">=</span> <span style="color:#ae81ff">2</span> <span style="color:#f92672">]</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> <span style="color:#f92672">[[</span> $a !<span style="color:#f92672">=</span> <span style="color:#ae81ff">1</span> <span style="color:#f92672">&amp;&amp;</span> $a !<span style="color:#f92672">=</span> <span style="color:#ae81ff">2</span> <span style="color:#f92672">]]</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">for</span> i in <span style="color:#66d9ef">$(</span>seq <span style="color:#ae81ff">0</span> 4<span style="color:#66d9ef">)</span>;<span style="color:#66d9ef">do</span> echo $i;<span style="color:#66d9ef">done</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">for</span> i in <span style="color:#ae81ff">\`</span>seq <span style="color:#ae81ff">0</span> 4<span style="color:#ae81ff">\`</span>;<span style="color:#66d9ef">do</span> echo $i;<span style="color:#66d9ef">done</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">for</span> <span style="color:#f92672">((</span>i<span style="color:#f92672">=</span>0;i&lt;5;i++<span style="color:#f92672">))</span>;<span style="color:#66d9ef">do</span> echo $i;<span style="color:#66d9ef">done</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">for</span> i in <span style="color:#f92672">{</span>0..4<span style="color:#f92672">}</span>;<span style="color:#66d9ef">do</span> echo $i;<span style="color:#66d9ef">done</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="-和-">
  <a class="anchor inpage" href="#-%e5%92%8c-">###</a><code>[]</code> 和 <code>[[]]</code></h3>
<p>在 <strong>Bash</strong> 脚本中，<code>[ ]</code>（<code>test</code> 命令）和 <code>[[ ]]</code>（关键字）都用于条件判断，但它们在功能、性能和安全性上有显著区别。以下是详细对比：</p>
<h4 id="基本定义">
  <a class="anchor inpage" href="#%e5%9f%ba%e6%9c%ac%e5%ae%9a%e4%b9%89">####</a>基本定义</h4>
<table>
  <thead>
      <tr>
          <th>语法</th>
          <th>类型</th>
          <th>说明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>[ ]</code></td>
          <td><strong>内置命令</strong></td>
          <td>等价于 <code>test</code> 命令，需严格遵循参数规则（如空格和引号）。</td>
      </tr>
      <tr>
          <td><code>[[ ]]</code></td>
          <td><strong>Shell 关键字</strong></td>
          <td>Bash/ksh/zsh 的扩展语法，更灵活，支持额外功能（如模式匹配、逻辑组合）。</td>
      </tr>
  </tbody>
</table>
<h4 id="核心区别">
  <a class="anchor inpage" href="#%e6%a0%b8%e5%bf%83%e5%8c%ba%e5%88%ab">####</a>核心区别</h4>
<p><strong>(1) 字符串比较</strong></p>
<ul>
<li>
<p><strong><code>[ ]</code></strong>：</p>
<ul>
<li>使用 <code>=</code> 和 <code>!=</code> 时，<strong>必须加引号</strong>，否则可能因空格或特殊字符报错。</li>
<li>示例：
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#f92672">[</span> <span style="color:#e6db74">&#34;</span>$var<span style="color:#e6db74">&#34;</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;hello&#34;</span> <span style="color:#f92672">]</span>  <span style="color:#75715e"># 正确</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">[</span> $var <span style="color:#f92672">=</span> hello <span style="color:#f92672">]</span>      <span style="color:#75715e"># 若 $var 含空格，会报错</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
</ul>
</li>
<li>
<p><strong><code>[[ ]]</code></strong>：</p>
<ul>
<li>自动处理变量中的空格，无需引号（但仍建议加引号以防未定义变量）。</li>
<li>支持 <code>==</code> 和 <code>!=</code> 的<strong>通配符匹配</strong>（模式匹配）。</li>
<li>示例：
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#f92672">[[</span> $var <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;hello&#34;</span> <span style="color:#f92672">]]</span>    <span style="color:#75715e"># 正确，即使 $var 含空格</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">[[</span> $var <span style="color:#f92672">==</span> h* <span style="color:#f92672">]]</span>         <span style="color:#75715e"># 支持通配符匹配（如 &#34;hello&#34; 或 &#34;hi&#34;）</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
</ul>
</li>
</ul>
<p><strong>(2) 数值比较</strong></p>
<ul>
<li>
<p><strong><code>[ ]</code></strong>：</p>
<ul>
<li>必须用 <code>-eq</code>、<code>-lt</code> 等运算符：
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#f92672">[</span> <span style="color:#e6db74">&#34;</span>$num<span style="color:#e6db74">&#34;</span> -lt <span style="color:#ae81ff">5</span> <span style="color:#f92672">]</span>  <span style="color:#75715e"># 数值比较</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
</ul>
</li>
<li>
<p><strong><code>[[ ]]</code></strong>：</p>
<ul>
<li>仍建议用 <code>-eq</code>、<code>-lt</code>，但支持 <code>&gt;</code> 和 <code>&lt;</code>（需转义或双括号）：
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#f92672">[[</span> $num -lt <span style="color:#ae81ff">5</span> <span style="color:#f92672">]]</span>    <span style="color:#75715e"># 标准写法</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">[[</span> $num &lt; <span style="color:#ae81ff">10</span> <span style="color:#f92672">]]</span>     <span style="color:#75715e"># 字符串比较（字典序）！</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">((</span> num &lt; <span style="color:#ae81ff">10</span> <span style="color:#f92672">))</span>      <span style="color:#75715e"># 数值比较的正确写法</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
</ul>
</li>
</ul>
<p><strong>(3) 逻辑运算符</strong></p>
<ul>
<li>
<p><strong><code>[ ]</code></strong>：</p>
<ul>
<li>用 <code>-a</code>（AND）、<code>-o</code>（OR），需严格分隔：
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#f92672">[</span> <span style="color:#e6db74">&#34;</span>$a<span style="color:#e6db74">&#34;</span> -gt <span style="color:#ae81ff">1</span> -a <span style="color:#e6db74">&#34;</span>$a<span style="color:#e6db74">&#34;</span> -lt <span style="color:#ae81ff">10</span> <span style="color:#f92672">]</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
</ul>
</li>
<li>
<p><strong><code>[[ ]]</code></strong>：</p>
<ul>
<li>用 <code>&amp;&amp;</code> 和 <code>||</code>，更直观：
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#f92672">[[</span> $a -gt <span style="color:#ae81ff">1</span> <span style="color:#f92672">&amp;&amp;</span> $a -lt <span style="color:#ae81ff">10</span> <span style="color:#f92672">]]</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
</ul>
</li>
</ul>
<p><strong>(4) 文件测试</strong></p>
<ul>
<li><strong><code>[ ]</code></strong> 和 <code>[[ ]]</code> 均支持，但 <code>[[ ]]</code> 更安全（如未定义变量不会报错）：
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#f92672">[</span> -f <span style="color:#e6db74">&#34;</span>$file<span style="color:#e6db74">&#34;</span> <span style="color:#f92672">]</span>      <span style="color:#75715e"># 检查文件是否存在</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">[[</span> -f $file <span style="color:#f92672">]]</span>      <span style="color:#75715e"># 更健壮（即使 $file 未定义也不会语法错误）</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
</ul>
<p><strong>(5) 正则匹配（仅 <code>[[ ]]</code>）</strong></p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#f92672">[[</span> <span style="color:#e6db74">&#34;hello&#34;</span> <span style="color:#f92672">=</span>~ ^h <span style="color:#f92672">]]</span>   <span style="color:#75715e"># 正则匹配（返回 true）</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h4 id="性能与安全性">
  <a class="anchor inpage" href="#%e6%80%a7%e8%83%bd%e4%b8%8e%e5%ae%89%e5%85%a8%e6%80%a7">####</a>性能与安全性</h4>
<table>
  <thead>
      <tr>
          <th>特性</th>
          <th><code>[ ]</code></th>
          <th><code>[[ ]]</code></th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>执行速度</strong></td>
          <td>较慢（外部命令或内置命令）</td>
          <td>更快（Bash 关键字）</td>
      </tr>
      <tr>
          <td><strong>安全性</strong></td>
          <td>变量未加引号易报错</td>
          <td>自动处理空格，更健壮</td>
      </tr>
      <tr>
          <td><strong>兼容性</strong></td>
          <td>所有 Shell（sh、dash 等）</td>
          <td>仅 Bash/ksh/zsh</td>
      </tr>
  </tbody>
</table>
<h4 id="何时使用">
  <a class="anchor inpage" href="#%e4%bd%95%e6%97%b6%e4%bd%bf%e7%94%a8">####</a>何时使用？</h4>
<ul>
<li><strong>用 <code>[[ ]]</code></strong>：
<ul>
<li>需要模式匹配、正则表达式、逻辑组合时。</li>
<li>脚本已明确使用 Bash（<code>#!/bin/bash</code>）。</li>
</ul>
</li>
<li><strong>用 <code>[ ]</code></strong>：
<ul>
<li>需兼容 POSIX Shell（如 <code>/bin/sh</code>）。</li>
<li>简单的文件或字符串测试（但务必加引号）。</li>
</ul>
</li>
</ul>
<h4 id="经典示例">
  <a class="anchor inpage" href="#%e7%bb%8f%e5%85%b8%e7%a4%ba%e4%be%8b">####</a>经典示例</h4>
<p><strong>(1) 字符串比较</strong></p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#75715e"># [ ] 必须加引号</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">[</span> <span style="color:#e6db74">&#34;</span>$name<span style="color:#e6db74">&#34;</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;Alice&#34;</span> <span style="color:#f92672">]</span> <span style="color:#f92672">&amp;&amp;</span> echo <span style="color:#e6db74">&#34;Hello Alice&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># [[ ]] 更灵活</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">[[</span> $name <span style="color:#f92672">==</span> A* <span style="color:#f92672">]]</span> <span style="color:#f92672">&amp;&amp;</span> echo <span style="color:#e6db74">&#34;Name starts with A&#34;</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p><strong>(2) 文件检查</strong></p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#75715e"># [ ] 和 [[ ]] 均可，但后者更安全</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">[</span> -f <span style="color:#e6db74">&#34;/path/</span>$file<span style="color:#e6db74">&#34;</span> <span style="color:#f92672">]</span> <span style="color:#f92672">&amp;&amp;</span> echo <span style="color:#e6db74">&#34;File exists&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">[[</span> -f /path/$file <span style="color:#f92672">]]</span> <span style="color:#f92672">&amp;&amp;</span> echo <span style="color:#e6db74">&#34;File exists&#34;</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p><strong>(3) 逻辑组合</strong></p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#75715e"># [ ] 用 -a/-o</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">[</span> <span style="color:#e6db74">&#34;</span>$age<span style="color:#e6db74">&#34;</span> -gt <span style="color:#ae81ff">18</span> -a <span style="color:#e6db74">&#34;</span>$age<span style="color:#e6db74">&#34;</span> -lt <span style="color:#ae81ff">60</span> <span style="color:#f92672">]</span> <span style="color:#f92672">&amp;&amp;</span> echo <span style="color:#e6db74">&#34;Valid age&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># [[ ]] 用 &amp;&amp;/||</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">[[</span> $age -gt <span style="color:#ae81ff">18</span> <span style="color:#f92672">&amp;&amp;</span> $age -lt <span style="color:#ae81ff">60</span> <span style="color:#f92672">]]</span> <span style="color:#f92672">&amp;&amp;</span> echo <span style="color:#e6db74">&#34;Valid age&#34;</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h4 id="总结">
  <a class="anchor inpage" href="#%e6%80%bb%e7%bb%93">####</a>总结</h4>
<table>
  <thead>
      <tr>
          <th><strong>需求</strong></th>
          <th><strong><code>[ ]</code></strong></th>
          <th><strong><code>[[ ]]</code></strong></th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>字符串比较</td>
          <td>需严格加引号</td>
          <td>自动处理空格，支持通配符</td>
      </tr>
      <tr>
          <td>数值比较</td>
          <td>用 <code>-eq</code>、<code>-lt</code></td>
          <td>同 <code>[ ]</code>，但可用 <code>(( ))</code> 替代</td>
      </tr>
      <tr>
          <td>逻辑运算符</td>
          <td><code>-a</code>、<code>-o</code></td>
          <td><code>&amp;&amp;</code>、<code>||</code></td>
      </tr>
      <tr>
          <td>正则匹配</td>
          <td>❌</td>
          <td>✅（<code>=~</code>）</td>
      </tr>
      <tr>
          <td>性能</td>
          <td>较慢</td>
          <td>更快</td>
      </tr>
  </tbody>
</table>
<ul>
<li><strong>优先用 <code>[[ ]]</code></strong>（Bash 脚本中更安全、灵活）。</li>
<li><strong>只有需要兼容 POSIX 时用 <code>[ ]</code></strong>（如 <code>/bin/sh</code> 脚本）。</li>
</ul>
<h3 id="heading-2">
  <a class="anchor inpage" href="#heading-2">###</a><code>()</code></h3>
<ul>
<li><strong>命令组</strong> 。括号中的命令将会新开一个子shell顺序执行，所以括号中的变量不能够被脚本余下的部分使用。括号中多个命令之间用分号隔开，最后一个命令可以没有分号，各命令和括号之间不必有空格。</li>
<li><strong>命令替换</strong> 。等同于<code>cmd</code>，shell扫描一遍命令行，发现了<code>$(cmd)</code>结构，便将<code>$(cmd)</code>中的<code>cmd</code>执行一次，得到其标准输出，再将此输出放到原来命令。有些shell不支持，如tcsh。</li>
<li><strong>用于初始化数组</strong> 。如：<code>array=(a b c d)</code></li>
</ul>
<h3 id="heading-3">
  <a class="anchor inpage" href="#heading-3">###</a><code>(())</code></h3>
<ul>
<li>整数扩展。这种扩展计算是整数型的计算，不支持浮点型。((exp))结构扩展并计算一个算术表达式的值，如果表达式的结果为0，那么返回的退出状态码为1，或者 是&quot;假&quot;，而一个非零值的表达式所返回的退出状态码将为0，或者是&quot;true&quot;。若是逻辑判断，表达式exp为真则为1,假则为0。</li>
<li>只要括号中的运算符、表达式符合C语言运算规则，都可用在$((exp))中，甚至是三目运算符。作不同进位(如二进制、八进制、十六进制)运算时，输出结果全都自动转化成了十进制。如：echo $((16#5f)) 结果为95 (16进位转十进制)</li>
<li>单纯用 (( )) 也可重定义变量值，比如 a=5; ((a++)) 可将 $a 重定义为6</li>
<li>常用于算术运算比较，双括号中的变量可以不使用<code>$</code>符号前缀。括号内支持多个表达式用逗号分开。 只要括号中的表达式符合C语言运算规则,比如可以直接使用<code>for((i=0;i&lt;5;i++))</code>, 如果不使用双括号, 则为<code>for i in $(seq 0 4)</code>或者<code>for i in {0..4}</code>。再如可以直接使用<code>if (($i&lt;5))</code>, 如果不使用双括号, 则为<code>if \[ $i -lt 5 \]</code>。</li>
</ul>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span>var<span style="color:#f92672">=</span><span style="color:#66d9ef">$((</span>expression<span style="color:#66d9ef">))</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="-back-ticks">
  <a class="anchor inpage" href="#-back-ticks">###</a><code>``</code> back ticks</h3>
<p>var= commands</p>
<p><strong>Example</strong>: Suppose we want to get the output of a list of mountpoints with <code>tmpfs</code> in their name. We can craft a statement like this: <code>df -h | grep tmpfs</code>.</p>
<p>To include it in the bash script, we can enclose it in back ticks.</p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#75715e">#!/bin/bash
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>
</span></span><span style="display:flex;"><span>var<span style="color:#f92672">=</span><span style="color:#ae81ff">\`</span>df -h | grep tmpfs<span style="color:#ae81ff">\`</span>
</span></span><span style="display:flex;"><span>echo $var</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="heading-4">
  <a class="anchor inpage" href="#heading-4">###</a><code>&quot;&quot;</code></h3>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span>repo<span style="color:#f92672">=</span>~<span style="color:#e6db74">&#34;/projects/repo1&#34;</span>  <span style="color:#75715e"># 或直接写 ~/projects/repo1（不加引号）</span>
</span></span><span style="display:flex;"><span>cd <span style="color:#e6db74">&#34;</span>$repo<span style="color:#e6db74">&#34;</span>               <span style="color:#75715e"># 此时 $repo 已是展开后的绝对路径</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#75715e">#!/bin/bash
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 显式展开家目录</span>
</span></span><span style="display:flex;"><span>HOME_DIR<span style="color:#f92672">=</span><span style="color:#66d9ef">$(</span>eval echo <span style="color:#e6db74">&#34;~&#34;</span><span style="color:#66d9ef">)</span>  <span style="color:#75715e"># 或直接写 HOME_DIR=&#34;$HOME&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>repos<span style="color:#f92672">=(</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;</span>$HOME_DIR<span style="color:#e6db74">/projects/repo1&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;</span>$HOME_DIR<span style="color:#e6db74">/work/repo2&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">)</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="-和--1">
  <a class="anchor inpage" href="#-%e5%92%8c--1">###</a><code>&quot;&quot;</code> 和 <code>''</code></h3>
<p>在 <strong>Bash</strong> 脚本中，双引号 <code>&quot;&quot;</code> 和单引号 <code>''</code> 都用于定义字符串，但它们在 <strong>变量扩展</strong>、<strong>命令替换</strong> 和 <strong>特殊字符处理</strong> 上有本质区别。以下是详细对比：</p>
<table>
  <thead>
      <tr>
          <th>特性</th>
          <th>双引号 <code>&quot;&quot;</code></th>
          <th>单引号 <code>''</code></th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>变量扩展</strong></td>
          <td>✅（如 <code>&quot;$var&quot;</code> 会展开）</td>
          <td>❌（如 <code>'$var'</code> 原样输出）</td>
      </tr>
      <tr>
          <td><strong>命令替换</strong></td>
          <td>✅（如 <code>&quot;$(date)&quot;</code> 会执行）</td>
          <td>❌（如 <code>'$(date)'</code> 原样输出）</td>
      </tr>
      <tr>
          <td><strong>转义字符</strong></td>
          <td>仅 <code>\</code>, <code>$</code>, <code>`</code>, <code>&quot;</code> 生效</td>
          <td>所有字符均按字面处理（无转义）</td>
      </tr>
      <tr>
          <td><strong>用途</strong></td>
          <td>需保留变量或命令结果时使用</td>
          <td>需完全按字面输出时使用</td>
      </tr>
  </tbody>
</table>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span>name<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;Alice&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>echo <span style="color:#e6db74">&#34;Hello, </span>$name<span style="color:#e6db74">&#34;</span>   <span style="color:#75715e"># 输出: Hello, Alice</span>
</span></span><span style="display:flex;"><span>echo <span style="color:#e6db74">&#39;Hello, $name&#39;</span>   <span style="color:#75715e"># 输出: Hello, $name</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span>echo <span style="color:#e6db74">&#34;Today is </span><span style="color:#66d9ef">$(</span>date<span style="color:#66d9ef">)</span><span style="color:#e6db74">&#34;</span>  <span style="color:#75715e"># 输出: Today is Mon Jul 1 12:00:00 UTC 2024</span>
</span></span><span style="display:flex;"><span>echo <span style="color:#e6db74">&#39;Today is $(date)&#39;</span>  <span style="color:#75715e"># 输出: Today is $(date)</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span>echo <span style="color:#e6db74">&#34;Path is \$HOME&#34;</span>    <span style="color:#75715e"># 输出: Path is $HOME（\$ 被转义）</span>
</span></span><span style="display:flex;"><span>echo <span style="color:#e6db74">&#39;Path is \$HOME&#39;</span>    <span style="color:#75715e"># 输出: Path is \$HOME（完全字面）</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span>echo <span style="color:#e6db74">&#34;She said: &#39;Hello!&#39;&#34;</span>   <span style="color:#75715e"># 输出: She said: &#39;Hello!&#39;</span>
</span></span><span style="display:flex;"><span>echo <span style="color:#e6db74">&#39;He said: &#34;Hi!&#34;&#39;</span>       <span style="color:#75715e"># 输出: He said: &#34;Hi!&#34;</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><ul>
<li>
<p>需要<strong>变量或命令替换</strong>时：</p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span>echo <span style="color:#e6db74">&#34;Current user: </span>$USER<span style="color:#e6db74">, time: </span><span style="color:#66d9ef">$(</span>date<span style="color:#66d9ef">)</span><span style="color:#e6db74">&#34;</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
<li>
<p>字符串中包含<strong>空格或特殊字符</strong>（需部分转义）：</p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span>echo <span style="color:#e6db74">&#34;Use \&#34;quotes\&#34; inside.&#34;</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
<li>
<p>需<strong>完全按字面输出</strong>（如正则表达式、SQL语句）：</p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span>grep -E <span style="color:#e6db74">&#39;^[A-Z]&#39;</span> file.txt  <span style="color:#75715e"># 正则表达式</span>
</span></span><span style="display:flex;"><span>sql<span style="color:#f92672">=</span><span style="color:#e6db74">&#39;SELECT * FROM users;&#39;</span> <span style="color:#75715e"># SQL语句</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
<li>
<p>避免<strong>特殊字符被解析</strong>：</p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span>echo <span style="color:#e6db74">&#39;$PATH and $(date)&#39;</span>  <span style="color:#75715e"># 输出: $PATH and $(date)</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
</ul>
<p><strong>特殊情况处理</strong></p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span>alias rm<span style="color:#f92672">=</span><span style="color:#e6db74">&#39;rm -i&#39;</span>          <span style="color:#75715e"># 单引号内定义别名（避免变量提前展开）</span>
</span></span><span style="display:flex;"><span>echo <span style="color:#e6db74">&#34;It&#39;s a sunny day.&#34;</span>  <span style="color:#75715e"># 双引号内嵌套单引号（无需转义）</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span>echo <span style="color:#e6db74">&#34;Line 1\nLine 2&#34;</span>     <span style="color:#75715e"># 输出: Line 1\nLine 2（\n 未被转义为换行）</span>
</span></span><span style="display:flex;"><span>echo -e <span style="color:#e6db74">&#34;Line 1\nLine 2&#34;</span>  <span style="color:#75715e"># 输出两行（-e 启用转义）</span>
</span></span><span style="display:flex;"><span>echo <span style="color:#e6db74">&#39;Line 1\nLine 2&#39;</span>     <span style="color:#75715e"># 输出: Line 1\nLine 2（完全字面）</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><ul>
<li><strong>单引号稍快</strong>：因为无需解析变量或命令替换。</li>
<li>实际脚本中差异可忽略，优先考虑功能需求。</li>
</ul>
<ol>
<li><strong>默认用双引号</strong>：<br>
保护变量中的空格（如 <code>&quot;$file&quot;</code>），避免路径或文件名错误拆分。
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span>cp <span style="color:#e6db74">&#34;</span>$file<span style="color:#e6db74">&#34;</span> <span style="color:#e6db74">&#34;/backup/</span>$file<span style="color:#e6db74">&#34;</span>  <span style="color:#75715e"># 正确处理含空格的文件名</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
<li><strong>需要纯文本时用单引号</strong>：<br>
如正则表达式、代码生成、避免意外展开。
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span>sed -e <span style="color:#e6db74">&#39;s/foo/bar/g&#39;</span> file.txt</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
</ol>
<h2 id="read-write">
  <a class="anchor inpage" href="#read-write">##</a>read, write</h2>
<h3 id="read">
  <a class="anchor inpage" href="#read">###</a>read</h3>
<h4 id="read-in-console">
  <a class="anchor inpage" href="#read-in-console">####</a>read in console</h4>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span>echo <span style="color:#e6db74">&#34;input a&#34;</span>
</span></span><span style="display:flex;"><span>read a
</span></span><span style="display:flex;"><span>echo <span style="color:#e6db74">&#34;input b&#34;</span>
</span></span><span style="display:flex;"><span>read b
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>read -n <span style="color:#ae81ff">3</span> -t <span style="color:#ae81ff">5</span> -s -p <span style="color:#e6db74">&#34;input 3 charater, wait for 5 seconds, silent&#34;</span> c
</span></span><span style="display:flex;"><span>echo <span style="color:#e6db74">&#34;</span>$c<span style="color:#e6db74">&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>printf <span style="color:#e6db74">&#34;a=%s,b=%s,sum is %s&#34;</span> $a $b <span style="color:#66d9ef">$((</span>a <span style="color:#f92672">+</span> b<span style="color:#66d9ef">))</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>It is possible to give arguments to the script on execution.</p>
<p><code>$@</code> is a list of the parameters.</p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#75715e">#!/bin/bash
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">for</span> x in $@
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">do</span>
</span></span><span style="display:flex;"><span>    echo <span style="color:#e6db74">&#34;Entered arg is </span>$x<span style="color:#e6db74">&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">done</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Run it like this:</p>
<p><code>./script arg1 arg2</code></p>
<h4 id="read-in-file">
  <a class="anchor inpage" href="#read-in-file">####</a>read in file</h4>
<p>Suppose we have a file <code>sample_file.txt</code>, We can read the file line by line and print the output on the screen.</p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#75715e">#!/bin/bash
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>
</span></span><span style="display:flex;"><span>LINE<span style="color:#f92672">=</span><span style="color:#ae81ff">1</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">while</span> read -r CURRENT_LINE
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">do</span>
</span></span><span style="display:flex;"><span>        echo <span style="color:#e6db74">&#34;</span>$LINE<span style="color:#e6db74">: </span>$CURRENT_LINE<span style="color:#e6db74">&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">((</span>LINE++<span style="color:#f92672">))</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">done</span> &lt; <span style="color:#e6db74">&#34;sample_file.txt&#34;</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="write">
  <a class="anchor inpage" href="#write">###</a>write</h3>
<h2 id="redirection-pipe">
  <a class="anchor inpage" href="#redirection-pipe">##</a>redirection, pipe</h2>
<h3 id="direction">
  <a class="anchor inpage" href="#direction">###</a>direction</h3>
<h4 id="输出重定向">
  <a class="anchor inpage" href="#%e8%be%93%e5%87%ba%e9%87%8d%e5%ae%9a%e5%90%91">####</a>输出重定向</h4>
<table>
  <thead>
      <tr>
          <th>符号</th>
          <th>作用</th>
          <th>示例</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>&gt;</code></td>
          <td>覆盖写入文件（标准输出）</td>
          <td><code>ls &gt; file.txt</code></td>
      </tr>
      <tr>
          <td><code>&gt;&gt;</code></td>
          <td>追加到文件（标准输出）</td>
          <td><code>echo &quot;hi&quot; &gt;&gt; file.txt</code></td>
      </tr>
      <tr>
          <td><code>2&gt;</code></td>
          <td>覆盖写入文件（标准错误）</td>
          <td><code>cmd 2&gt; error.log</code></td>
      </tr>
      <tr>
          <td><code>2&gt;&gt;</code></td>
          <td>追加到文件（标准错误）</td>
          <td><code>cmd 2&gt;&gt; error.log</code></td>
      </tr>
      <tr>
          <td><code>&amp;&gt;</code></td>
          <td>覆盖写入文件（标准输出+标准错误）</td>
          <td><code>cmd &amp;&gt; output.log</code></td>
      </tr>
      <tr>
          <td><code>&amp;&gt;&gt;</code></td>
          <td>追加到文件（标准输出+标准错误）</td>
          <td><code>cmd &amp;&gt;&gt; output.log</code></td>
      </tr>
  </tbody>
</table>
<p><strong>文件描述符操作</strong> Bash 用数字<code>n</code>表示文件描述符（File Descriptor, FD）：</p>
<ul>
<li><code>0</code>：标准输入（stdin）</li>
<li><code>1</code>：标准输出（stdout）</li>
<li><code>2</code>：标准错误（stderr）</li>
</ul>
<table>
  <thead>
      <tr>
          <th>符号</th>
          <th>作用</th>
          <th>示例</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>n&gt;</code></td>
          <td>覆盖写入到文件描述符 <code>n</code></td>
          <td><code>cmd 3&gt; custom_fd.log</code></td>
      </tr>
      <tr>
          <td><code>n&gt;&gt;</code></td>
          <td>追加到文件描述符 <code>n</code></td>
          <td><code>cmd 3&gt;&gt; custom_fd.log</code></td>
      </tr>
      <tr>
          <td><code>n&gt;&amp;m</code></td>
          <td>将文件描述符 <code>n</code> 重定向到 <code>m</code></td>
          <td><code>cmd 2&gt;&amp;1</code>（错误合并到输出）</td>
      </tr>
      <tr>
          <td><code>n&gt;&amp;-</code></td>
          <td>关闭文件描述符 <code>n</code></td>
          <td><code>exec 3&gt;&amp;-</code></td>
      </tr>
      <tr>
          <td><code>&amp;&gt;file</code> 或 <code>&gt;&amp;file</code></td>
          <td>合并标准输出和错误到文件（兼容性写法）</td>
          <td><code>cmd &amp;&gt; all.log</code></td>
      </tr>
  </tbody>
</table>
<p><strong>示例</strong>：</p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#75715e"># 将标准错误重定向到文件描述符3，再重定向到文件</span>
</span></span><span style="display:flex;"><span>exec 3&gt;&amp;<span style="color:#ae81ff">1</span>  <span style="color:#75715e"># 备份标准输出到3</span>
</span></span><span style="display:flex;"><span>cmd 2&gt;&amp;<span style="color:#ae81ff">1</span> &gt;output.log | tee -a error.log  <span style="color:#75715e"># 错误流单独处理</span>
</span></span><span style="display:flex;"><span>exec 1&gt;&amp;<span style="color:#ae81ff">3</span>  <span style="color:#75715e"># 恢复标准输出</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p><strong>特殊设备重定向</strong></p>
<table>
  <thead>
      <tr>
          <th>目标文件</th>
          <th>作用</th>
          <th>示例</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>/dev/null</code></td>
          <td>丢弃输出（黑洞设备）</td>
          <td><code>cmd &gt; /dev/null 2&gt;&amp;1</code></td>
      </tr>
      <tr>
          <td><code>/dev/stdout</code></td>
          <td>显式指向标准输出</td>
          <td><code>echo &quot;x&quot; &gt; /dev/stdout</code></td>
      </tr>
      <tr>
          <td><code>/dev/stderr</code></td>
          <td>显式指向标准错误</td>
          <td><code>echo &quot;error&quot; &gt; /dev/stderr</code></td>
      </tr>
      <tr>
          <td><code>/dev/fd/n</code></td>
          <td>重定向到文件描述符 <code>n</code></td>
          <td><code>cmd &gt; /dev/fd/3</code></td>
      </tr>
  </tbody>
</table>
<p><strong>示例</strong>：</p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#75715e"># 静默执行命令（忽略所有输出）</span>
</span></span><span style="display:flex;"><span>cmd &gt; /dev/null 2&gt;&amp;<span style="color:#ae81ff">1</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h4 id="输入重定向">
  <a class="anchor inpage" href="#%e8%be%93%e5%85%a5%e9%87%8d%e5%ae%9a%e5%90%91">####</a>输入重定向</h4>
<table>
  <thead>
      <tr>
          <th>符号</th>
          <th>作用</th>
          <th>示例</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>&lt;</code></td>
          <td>从文件读取输入（标准输入）</td>
          <td><code>sort &lt; data.txt</code></td>
      </tr>
      <tr>
          <td><code>&lt;&lt;</code></td>
          <td>Here Document（多行输入）</td>
          <td>见前文</td>
      </tr>
      <tr>
          <td><code>&lt;&lt;&lt;</code></td>
          <td>Here String（字符串输入）</td>
          <td><code>grep &quot;x&quot; &lt;&lt;&lt; &quot;abc&quot;</code></td>
      </tr>
  </tbody>
</table>
<p><strong><code>&lt;</code>：标准输入重定向</strong></p>
<p><strong>作用</strong>：将文件内容作为命令的标准输入。<br>
<strong>语法</strong>：<code>command &lt; file</code><br>
<strong>特点</strong>：</p>
<ul>
<li>从文件中读取数据并传递给命令</li>
<li>文件内容会逐行作为命令的输入</li>
</ul>
<p><strong>示例</strong>：</p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#75715e"># 将 file.txt 的内容作为 wc 命令的输入</span>
</span></span><span style="display:flex;"><span>wc -l &lt; file.txt</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p><strong>结果</strong>：统计 <code>file.txt</code> 的行数。</p>
<p><strong><code>&lt;&lt;</code>：Here Document（文档内嵌输入）</strong></p>
<p><strong>作用</strong>：将多行文本（称为 &ldquo;Here Document&rdquo;）作为命令的标准输入，直到遇到指定的结束标记。<br>
<strong>语法</strong>：</p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span>command <span style="color:#e6db74">&lt;&lt; DELIMITER
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">多行文本...
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">DELIMITER</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p><strong>特点</strong>：</p>
<ul>
<li>允许在脚本中直接嵌入多行输入</li>
<li>结束标记（<code>DELIMITER</code>）可以是任意字符串（通常用 <code>EOF</code>）</li>
<li>默认会解析变量和命令替换（除非用引号包围 <code>DELIMITER</code>，如 <code>&lt;&lt;'EOF'</code>）</li>
</ul>
<p><strong>示例</strong>：</p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#75715e"># 将多行文本传递给 cat 命令</span>
</span></span><span style="display:flex;"><span>cat <span style="color:#e6db74">&lt;&lt; EOF
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">第一行
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">第二行
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">变量值: $HOME
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">EOF</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p><strong>结果</strong>：</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">第一行
第二行
变量值: /home/username</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p><strong><code>&lt;&lt;&lt;</code>：Here String（字符串内嵌输入）</strong>
<strong>作用</strong>：将单个字符串作为命令的标准输入。<br>
<strong>语法</strong>：<code>command &lt;&lt;&lt; &quot;string&quot;</code><br>
<strong>特点</strong>：</p>
<ul>
<li>直接传递字符串（无需文件或多行文本）</li>
<li>字符串会解析变量和命令替换</li>
<li>比 <code>echo &quot;string&quot; | command</code> 更高效（避免管道和子进程）</li>
</ul>
<p><strong>示例</strong>：</p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#75715e"># 将字符串传递给 grep 命令</span>
</span></span><span style="display:flex;"><span>grep <span style="color:#e6db74">&#34;hello&#34;</span> <span style="color:#f92672">&lt;&lt;&lt;</span> <span style="color:#e6db74">&#34;hello world&#34;</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p><strong>结果</strong>：输出 <code>hello world</code>（因为匹配成功）。</p>
<p><strong>对比总结</strong></p>
<table>
  <thead>
      <tr>
          <th>操作符</th>
          <th>名称</th>
          <th>输入源</th>
          <th>典型用途</th>
          <th>是否解析变量</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>&lt;</code></td>
          <td>输入重定向</td>
          <td>文件</td>
          <td>从文件读取数据</td>
          <td>是</td>
      </tr>
      <tr>
          <td><code>&lt;&lt;</code></td>
          <td>Here Document</td>
          <td>多行文本（脚本内嵌）</td>
          <td>传递多行输入（如生成配置文件）</td>
          <td>是（可禁用）</td>
      </tr>
      <tr>
          <td><code>&lt;&lt;&lt;</code></td>
          <td>Here String</td>
          <td>单个字符串</td>
          <td>快速传递变量或简单字符串</td>
          <td>是</td>
      </tr>
  </tbody>
</table>
<p><strong>关键区别</strong></p>
<ol>
<li>
<p><strong>输入来源不同</strong>：</p>
<ul>
<li><code>&lt;</code> 从文件读取</li>
<li><code>&lt;&lt;</code> 从脚本内嵌的多行文本读取</li>
<li><code>&lt;&lt;&lt;</code> 从单个字符串读取</li>
</ul>
</li>
<li>
<p><strong>性能差异</strong>：</p>
<ul>
<li><code>&lt;&lt;&lt;</code> 比 <code>echo &quot;str&quot; | command</code> 更高效（避免管道）</li>
<li><code>&lt;</code> 适合处理大文件（逐行读取，不占用内存）</li>
</ul>
</li>
<li>
<p><strong>变量解析</strong>：</p>
<ul>
<li><code>&lt;&lt;</code> 和 <code>&lt;&lt;&lt;</code> 默认解析变量，但 <code>&lt;&lt;</code> 可通过 <code>&lt;&lt;'DELIMITER'</code> 禁用解析</li>
<li><code>&lt;</code> 由命令决定是否解析（如 <code>cat</code> 不解析，<code>eval</code> 会解析）</li>
</ul>
</li>
</ol>
<hr>
<p><strong>使用场景示例</strong>
<strong><code>&lt;</code> 的典型用途</strong></p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#75715e"># 从配置文件读取输入</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">while</span> read line; <span style="color:#66d9ef">do</span>
</span></span><span style="display:flex;"><span>    echo <span style="color:#e6db74">&#34;配置行: </span>$line<span style="color:#e6db74">&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">done</span> &lt; config.txt</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p><strong><code>&lt;&lt;</code> 的典型用途</strong></p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#75715e"># 生成多行配置文件</span>
</span></span><span style="display:flex;"><span>cat &gt; app.conf <span style="color:#e6db74">&lt;&lt; EOF
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">server_ip=192.168.1.1
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">port=8080
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">EOF</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p><strong><code>&lt;&lt;&lt;</code> 的典型用途</strong></p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#75715e"># 快速检查字符串是否包含子串</span>
</span></span><span style="display:flex;"><span>grep <span style="color:#e6db74">&#34;error&#34;</span> <span style="color:#f92672">&lt;&lt;&lt;</span> <span style="color:#e6db74">&#34;</span>$log_content<span style="color:#e6db74">&#34;</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p><strong>注意事项</strong></p>
<ol>
<li>
<p><strong><code>&lt;&lt;</code> 的结束标记</strong>：</p>
<ul>
<li>结束标记必须单独一行且顶格书写（不能有缩进）：
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#75715e"># 错误示例（缩进会导致语法错误）</span>
</span></span><span style="display:flex;"><span>cat <span style="color:#e6db74">&lt;&lt; EOF
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">内容...
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">  EOF</span>  <span style="color:#75715e"># 缩进了，无法识别为结束标记</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
</ul>
</li>
<li>
<p><strong><code>&lt;&lt;&lt;</code> 的字符串引用</strong>：</p>
<ul>
<li>如果字符串包含空格或特殊字符，需用引号包围：
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#75715e"># 安全写法</span>
</span></span><span style="display:flex;"><span>wc -w <span style="color:#f92672">&lt;&lt;&lt;</span> <span style="color:#e6db74">&#34;hello world&#34;</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
</ul>
</li>
<li>
<p><strong>性能选择</strong>：</p>
<ul>
<li>处理大量数据时优先用 <code>&lt;</code>（文件）或 <code>&lt;&lt;</code>（多行文本）</li>
<li>简单字符串操作用 <code>&lt;&lt;&lt;</code> 更高效</li>
</ul>
</li>
</ol>
<h4 id="重定向组合">
  <a class="anchor inpage" href="#%e9%87%8d%e5%ae%9a%e5%90%91%e7%bb%84%e5%90%88">####</a>重定向组合</h4>
<p><strong>(1) 同时重定向输入和输出</strong></p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#75715e"># 从input.txt读取，结果写入output.txt</span>
</span></span><span style="display:flex;"><span>command &lt; input.txt &gt; output.txt</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p><strong>(2) 分离标准输出和错误</strong></p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#75715e"># 标准输出到out.log，错误到err.log</span>
</span></span><span style="display:flex;"><span>command &gt; out.log 2&gt; err.log</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p><strong>(3) 合并输出和错误到同一文件</strong></p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#75715e"># 方式1（推荐）</span>
</span></span><span style="display:flex;"><span>command &amp;&gt; combined.log
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 方式2（传统写法）</span>
</span></span><span style="display:flex;"><span>command &gt; combined.log 2&gt;&amp;<span style="color:#ae81ff">1</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h4 id="进程替换process-substitution">
  <a class="anchor inpage" href="#%e8%bf%9b%e7%a8%8b%e6%9b%bf%e6%8d%a2process-substitution">####</a>进程替换（Process Substitution）</h4>
<p>用 <code>&gt;(...)</code> 和 <code>&lt;(...)</code> 将命令输出/输入视为临时文件：</p>
<table>
  <thead>
      <tr>
          <th>符号</th>
          <th>作用</th>
          <th>示例</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>&lt;(cmd)</code></td>
          <td>将命令输出作为文件输入</td>
          <td><code>diff &lt;(ls dir1) &lt;(ls dir2)</code></td>
      </tr>
      <tr>
          <td><code>&gt;(cmd)</code></td>
          <td>将命令输入作为文件输出</td>
          <td><code>tee &gt;(gzip &gt; out.gz)</code></td>
      </tr>
  </tbody>
</table>
<p><strong>示例</strong>：</p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#75715e"># 比较两个目录的文件列表差异</span>
</span></span><span style="display:flex;"><span>diff &lt;<span style="color:#f92672">(</span>ls /path/to/dir1<span style="color:#f92672">)</span> &lt;<span style="color:#f92672">(</span>ls /path/to/dir2<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 将输出同时写入文件和压缩</span>
</span></span><span style="display:flex;"><span>echo <span style="color:#e6db74">&#34;data&#34;</span> | tee &gt;<span style="color:#f92672">(</span>gzip &gt; output.gz<span style="color:#f92672">)</span> &gt; original.txt</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h4 id="综合示例">
  <a class="anchor inpage" href="#%e7%bb%bc%e5%90%88%e7%a4%ba%e4%be%8b">####</a>综合示例</h4>
<p>** 日志记录脚本**</p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#75715e">#!/bin/bash
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>exec 3&gt;&amp;<span style="color:#ae81ff">1</span>  <span style="color:#75715e"># 备份标准输出到描述符3</span>
</span></span><span style="display:flex;"><span>exec &gt; &gt;<span style="color:#f92672">(</span>tee -a stdout.log<span style="color:#f92672">)</span> 2&gt; &gt;<span style="color:#f92672">(</span>tee -a stderr.log &gt;&amp;2<span style="color:#f92672">)</span>  <span style="color:#75715e"># 分离输出和错误</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>echo <span style="color:#e6db74">&#34;正常消息&#34;</span>  <span style="color:#75715e"># 写入stdout.log</span>
</span></span><span style="display:flex;"><span>ls /nonexistent  <span style="color:#75715e"># 错误写入stderr.log</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>exec 1&gt;&amp;<span style="color:#ae81ff">3</span>  <span style="color:#75715e"># 恢复标准输出</span>
</span></span><span style="display:flex;"><span>echo <span style="color:#e6db74">&#34;回到终端显示&#34;</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p><strong>复杂重定向</strong></p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#f92672">{</span>
</span></span><span style="display:flex;"><span>    echo <span style="color:#e6db74">&#34;标准输出1&#34;</span>
</span></span><span style="display:flex;"><span>    echo <span style="color:#e6db74">&#34;标准错误1&#34;</span> &gt;&amp;<span style="color:#ae81ff">2</span>
</span></span><span style="display:flex;"><span>    echo <span style="color:#e6db74">&#34;标准输出2&#34;</span>
</span></span><span style="display:flex;"><span>    echo <span style="color:#e6db74">&#34;标准错误2&#34;</span> &gt;&amp;<span style="color:#ae81ff">2</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">}</span> &gt; &gt;<span style="color:#f92672">(</span>grep <span style="color:#e6db74">&#34;标准输出&#34;</span> &gt; out.txt<span style="color:#f92672">)</span> 2&gt; &gt;<span style="color:#f92672">(</span>grep <span style="color:#e6db74">&#34;标准错误&#34;</span> &gt; err.txt<span style="color:#f92672">)</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p><strong>注意事项</strong></p>
<ol>
<li>
<p><strong>顺序敏感</strong>：<br>
<code>2&gt;&amp;1 &gt;file</code> 和 <code>&gt;file 2&gt;&amp;1</code> 完全不同！后者才是合并输出到文件。</p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#75715e"># 错误：错误流不会进入文件</span>
</span></span><span style="display:flex;"><span>cmd 2&gt;&amp;<span style="color:#ae81ff">1</span> &gt; file
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 正确：合并输出和错误到文件</span>
</span></span><span style="display:flex;"><span>cmd &gt; file 2&gt;&amp;<span style="color:#ae81ff">1</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
<li>
<p><strong>文件描述符范围</strong>：<br>
Bash 默认支持 <code>0-9</code>，更高数值需用 <code>exec</code> 显式分配。</p>
</li>
<li>
<p><strong>管道与重定向优先级</strong>：<br>
管道 <code>|</code> 优先级高于重定向，必要时用 <code>{ }</code> 分组：</p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#f92672">{</span> cmd1 | cmd2; <span style="color:#f92672">}</span> &gt; output.txt</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
<li>
<p><strong>Here Document 的变体</strong>：</p>
<ul>
<li><code>&lt;&lt;-</code>：忽略结束标记前的制表符（Tab）
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span>cat <span style="color:#e6db74">&lt;&lt;- EOF
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    Indented text
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">EOF</span>  <span style="color:#75715e"># 可以用Tab缩进</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
</ul>
</li>
</ol>
<h3 id="pipe">
  <a class="anchor inpage" href="#pipe">###</a>pipe</h3>
<h2 id="control">
  <a class="anchor inpage" href="#control">##</a>control</h2>
<h3 id="if">
  <a class="anchor inpage" href="#if">###</a>if</h3>
<ul>
<li><code>if...then...fi</code> statements</li>
<li><code>if...then...else...fi</code> statements</li>
<li><code>if..elif..else..fi</code></li>
<li><code>if..then..else..if..then..fi..fi..</code> (Nested Conditionals)</li>
</ul>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#66d9ef">if</span> <span style="color:#f92672">[</span> ... <span style="color:#f92672">]</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">then</span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e"># if-code</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">else</span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e"># else-code</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">fi</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>or</p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#66d9ef">if</span> <span style="color:#f92672">[</span> ... <span style="color:#f92672">]</span> ; <span style="color:#66d9ef">then</span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e"># if-code</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">else</span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e"># else-code</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">fi</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>conditions:</p>
<p>examples:</p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#75715e">#!/bin/sh
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">if</span> <span style="color:#f92672">[</span> <span style="color:#e6db74">&#34;</span>$X<span style="color:#e6db74">&#34;</span> -lt <span style="color:#e6db74">&#34;0&#34;</span> <span style="color:#f92672">]</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">then</span>
</span></span><span style="display:flex;"><span>  echo <span style="color:#e6db74">&#34;X is less than zero&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">fi</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> <span style="color:#f92672">[</span> <span style="color:#e6db74">&#34;</span>$X<span style="color:#e6db74">&#34;</span> -gt <span style="color:#e6db74">&#34;0&#34;</span> <span style="color:#f92672">]</span>; <span style="color:#66d9ef">then</span>
</span></span><span style="display:flex;"><span>  echo <span style="color:#e6db74">&#34;X is more than zero&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">fi</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">[</span> <span style="color:#e6db74">&#34;</span>$X<span style="color:#e6db74">&#34;</span> -le <span style="color:#e6db74">&#34;0&#34;</span> <span style="color:#f92672">]</span> <span style="color:#f92672">&amp;&amp;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>      echo <span style="color:#e6db74">&#34;X is less than or equal to  zero&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">[</span> <span style="color:#e6db74">&#34;</span>$X<span style="color:#e6db74">&#34;</span> -ge <span style="color:#e6db74">&#34;0&#34;</span> <span style="color:#f92672">]</span> <span style="color:#f92672">&amp;&amp;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>      echo <span style="color:#e6db74">&#34;X is more than or equal to zero&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">[</span> <span style="color:#e6db74">&#34;</span>$X<span style="color:#e6db74">&#34;</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;0&#34;</span> <span style="color:#f92672">]</span> <span style="color:#f92672">&amp;&amp;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>      echo <span style="color:#e6db74">&#34;X is the string or number \&#34;0\&#34;&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">[</span> <span style="color:#e6db74">&#34;</span>$X<span style="color:#e6db74">&#34;</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;hello&#34;</span> <span style="color:#f92672">]</span> <span style="color:#f92672">&amp;&amp;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>      echo <span style="color:#e6db74">&#34;X matches the string \&#34;hello\&#34;&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">[</span> <span style="color:#e6db74">&#34;</span>$X<span style="color:#e6db74">&#34;</span> !<span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;hello&#34;</span> <span style="color:#f92672">]</span> <span style="color:#f92672">&amp;&amp;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>      echo <span style="color:#e6db74">&#34;X is not the string \&#34;hello\&#34;&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">[</span> -n <span style="color:#e6db74">&#34;</span>$X<span style="color:#e6db74">&#34;</span> <span style="color:#f92672">]</span> <span style="color:#f92672">&amp;&amp;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>      echo <span style="color:#e6db74">&#34;X is of nonzero length&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">[</span> -f <span style="color:#e6db74">&#34;</span>$X<span style="color:#e6db74">&#34;</span> <span style="color:#f92672">]</span> <span style="color:#f92672">&amp;&amp;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>      echo <span style="color:#e6db74">&#34;X is the path of a real file&#34;</span> <span style="color:#f92672">||</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>      echo <span style="color:#e6db74">&#34;No such file: </span>$X<span style="color:#e6db74">&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">[</span> -x <span style="color:#e6db74">&#34;</span>$X<span style="color:#e6db74">&#34;</span> <span style="color:#f92672">]</span> <span style="color:#f92672">&amp;&amp;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>      echo <span style="color:#e6db74">&#34;X is the path of an executable file&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">[</span> <span style="color:#e6db74">&#34;</span>$X<span style="color:#e6db74">&#34;</span> -nt <span style="color:#e6db74">&#34;/etc/passwd&#34;</span> <span style="color:#f92672">]</span> <span style="color:#f92672">&amp;&amp;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>      echo <span style="color:#e6db74">&#34;X is a file which is newer than /etc/passwd&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>read a
</span></span><span style="display:flex;"><span>read b
</span></span><span style="display:flex;"><span>read c
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> <span style="color:#f92672">[</span> $a <span style="color:#f92672">==</span> $b -a $b <span style="color:#f92672">==</span> $c -a $a <span style="color:#f92672">==</span> $c <span style="color:#f92672">]</span> <span style="color:#75715e"># -a means</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">then</span>
</span></span><span style="display:flex;"><span>echo EQUILATERAL
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">elif</span> <span style="color:#f92672">[</span> $a <span style="color:#f92672">==</span> $b -o $b <span style="color:#f92672">==</span> $c -o $a <span style="color:#f92672">==</span> $c <span style="color:#f92672">]</span> <span style="color:#75715e"># -o means or</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">then</span>
</span></span><span style="display:flex;"><span>echo ISOSCELES
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">else</span>
</span></span><span style="display:flex;"><span>echo SCALENE
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">fi</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="loop">
  <a class="anchor inpage" href="#loop">###</a>loop</h3>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">for</span> i in <span style="color:#f92672">{</span>1..5<span style="color:#f92672">}</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">do</span>
</span></span><span style="display:flex;"><span>    echo $i
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">done</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">for</span> X in cyan magenta yellow
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">do</span>
</span></span><span style="display:flex;"><span>    echo $X
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">done</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span>i<span style="color:#f92672">=</span><span style="color:#ae81ff">1</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">while</span> <span style="color:#f92672">[[</span> $i -le <span style="color:#ae81ff">10</span> <span style="color:#f92672">]]</span> ; <span style="color:#66d9ef">do</span>
</span></span><span style="display:flex;"><span>   echo <span style="color:#e6db74">&#34;</span>$i<span style="color:#e6db74">&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">((</span> i <span style="color:#f92672">+=</span> <span style="color:#ae81ff">1</span> <span style="color:#f92672">))</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">done</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#75715e"># 定义数组（空格分隔元素，可含特殊字符）</span>
</span></span><span style="display:flex;"><span>fruits<span style="color:#f92672">=(</span><span style="color:#e6db74">&#34;Apple&#34;</span> <span style="color:#e6db74">&#34;Banana&#34;</span> <span style="color:#e6db74">&#34;Orange&#34;</span> <span style="color:#e6db74">&#34;Grape&#34;</span> <span style="color:#e6db74">&#34;Watermelon&#34;</span><span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">for</span> fruit in <span style="color:#e6db74">&#34;</span><span style="color:#e6db74">${</span>fruits[@]<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>; <span style="color:#66d9ef">do</span>
</span></span><span style="display:flex;"><span>    echo <span style="color:#e6db74">&#34;Fruit: </span>$fruit<span style="color:#e6db74">&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">done</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">for</span> i in <span style="color:#e6db74">&#34;</span><span style="color:#e6db74">${</span>!fruits[@]<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>; <span style="color:#66d9ef">do</span>
</span></span><span style="display:flex;"><span>    echo <span style="color:#e6db74">&#34;Index </span>$i<span style="color:#e6db74">: </span><span style="color:#e6db74">${</span>fruits[i]<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">done</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#75715e"># 定义仓库目录列表（支持绝对路径或相对路径）</span>
</span></span><span style="display:flex;"><span>repos<span style="color:#f92672">=(</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;/path/to/repo1&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;/path/to/repo2&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;/path/to/repo3&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;/path/to/repo4&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 遍历所有仓库</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">for</span> i in <span style="color:#e6db74">&#34;</span><span style="color:#e6db74">${</span>repos[@]<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>; <span style="color:#66d9ef">do</span>
</span></span><span style="display:flex;"><span>    echo <span style="color:#e6db74">&#34;Updating repo: </span>$i<span style="color:#e6db74">&#34;</span>
</span></span><span style="display:flex;"><span>    cd <span style="color:#e6db74">&#34;</span>$i<span style="color:#e6db74">&#34;</span> <span style="color:#f92672">||</span> <span style="color:#f92672">{</span> echo <span style="color:#e6db74">&#34;Failed to enter </span>$i<span style="color:#e6db74">&#34;</span>; <span style="color:#66d9ef">continue</span>; <span style="color:#f92672">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># 执行 git pull</span>
</span></span><span style="display:flex;"><span>    git pull origin main  <span style="color:#75715e"># 假设分支是 main，根据实际情况修改</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># 检查 git pull 是否成功</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> <span style="color:#f92672">[</span> $? -eq <span style="color:#ae81ff">0</span> <span style="color:#f92672">]</span>; <span style="color:#66d9ef">then</span>
</span></span><span style="display:flex;"><span>        echo <span style="color:#e6db74">&#34;Successfully updated: </span>$i<span style="color:#e6db74">&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">else</span>
</span></span><span style="display:flex;"><span>        echo <span style="color:#e6db74">&#34;Failed to update: </span>$i<span style="color:#e6db74">&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">fi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    echo <span style="color:#e6db74">&#34;----------------------------------&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">done</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>echo <span style="color:#e6db74">&#34;All repositories updated!&#34;</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h2 id="function">
  <a class="anchor inpage" href="#function">##</a>function</h2>
<blockquote class="alert alert-warning">
      <p class="alert-heading"><br></p><p><strong>fork boom!</strong></p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">:(){:|:;};:</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></blockquote><h2 id="advance">
  <a class="anchor inpage" href="#advance">##</a>Advance</h2>
<h3 id="get-opts">
  <a class="anchor inpage" href="#get-opts">###</a>get-opts</h3>
<p>example:</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span><span style="color:#75715e">#!/bin/sh
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>docs<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;Usage: \
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">\n\tbash </span>$0<span style="color:#e6db74"> [options] \
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">\nOptions: \
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">\n\t-N NAME: your name, required\
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">\n\t-a AGE: your age, required\
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">\n\t-v: verbose mode, optional\
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">\nExample: \
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">\n\t bash </span>$0<span style="color:#e6db74"> -N balabala -a 24 &#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>usage<span style="color:#f92672">()</span> <span style="color:#f92672">{</span>
</span></span><span style="display:flex;"><span>    echo -e $docs &gt;&amp;<span style="color:#ae81ff">2</span>
</span></span><span style="display:flex;"><span>    exit <span style="color:#ae81ff">1</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> <span style="color:#f92672">[</span> $# -eq <span style="color:#ae81ff">0</span> <span style="color:#f92672">]</span> <span style="color:#f92672">||</span> <span style="color:#f92672">[</span> $1 <span style="color:#f92672">==</span> -h <span style="color:#f92672">]</span>; <span style="color:#66d9ef">then</span> usage; <span style="color:#66d9ef">fi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">## 设置变量的默认值</span>
</span></span><span style="display:flex;"><span>verbose<span style="color:#f92672">=</span>n
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">## 检查变量参数是否缺失</span>
</span></span><span style="display:flex;"><span>check<span style="color:#f92672">()</span> <span style="color:#f92672">{</span>
</span></span><span style="display:flex;"><span>    opt<span style="color:#f92672">=</span>$1
</span></span><span style="display:flex;"><span>    arg<span style="color:#f92672">=</span>$2
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> <span style="color:#f92672">[[</span> $arg <span style="color:#f92672">=</span>~ ^- <span style="color:#f92672">]]</span> <span style="color:#f92672">||</span> <span style="color:#f92672">[</span> ! $arg <span style="color:#f92672">]</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">then</span>
</span></span><span style="display:flex;"><span>        echo <span style="color:#e6db74">&#34;ERROR: -</span>$opt<span style="color:#e6db74"> expects an corresponding argument&#34;</span> &gt;&amp;<span style="color:#ae81ff">2</span>
</span></span><span style="display:flex;"><span>        usage
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">fi</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">## 循环解析脚本的所有positional parameters</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">while</span> getopts :vN:a: opt
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">do</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">case</span> $opt in
</span></span><span style="display:flex;"><span>    v<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>        verbose<span style="color:#f92672">=</span>y
</span></span><span style="display:flex;"><span>        ;;
</span></span><span style="display:flex;"><span>    N<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>        check N $OPTARG
</span></span><span style="display:flex;"><span>        name<span style="color:#f92672">=</span>$OPTARG
</span></span><span style="display:flex;"><span>        ;;
</span></span><span style="display:flex;"><span>    a<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>        check a $OPTARG
</span></span><span style="display:flex;"><span>        age<span style="color:#f92672">=</span>$OPTARG
</span></span><span style="display:flex;"><span>        ;;
</span></span><span style="display:flex;"><span>    :<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>        echo <span style="color:#e6db74">&#34;ERROR: -</span>$OPTARG<span style="color:#e6db74"> expects an corresponding argument&#34;</span> &gt;&amp;<span style="color:#ae81ff">2</span>
</span></span><span style="display:flex;"><span>        usage
</span></span><span style="display:flex;"><span>        ;;
</span></span><span style="display:flex;"><span>    <span style="color:#ae81ff">\?</span><span style="color:#f92672">)</span> <span style="color:#75715e"># shell里&#39;?&#39;具有匹配一位任意字符的作用，因此需要转义为普通字符</span>
</span></span><span style="display:flex;"><span>        echo <span style="color:#e6db74">&#34;ERROR: unkown option -</span>$OPTARG<span style="color:#e6db74">&#34;</span> &gt;&amp;<span style="color:#ae81ff">2</span>
</span></span><span style="display:flex;"><span>        usage
</span></span><span style="display:flex;"><span>        ;;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">esac</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">done</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">## 如果用户没有提供-N选项</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> <span style="color:#f92672">[</span> ! $name <span style="color:#f92672">]</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">then</span>
</span></span><span style="display:flex;"><span>    echo ERROR: option -N is required &gt;&amp;<span style="color:#ae81ff">2</span>
</span></span><span style="display:flex;"><span>    usage
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">fi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">## 如果用户没有提供-a选项</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> <span style="color:#f92672">[</span> ! $age <span style="color:#f92672">]</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">then</span>
</span></span><span style="display:flex;"><span>    echo ERROR: option -a is required &gt;&amp;<span style="color:#ae81ff">2</span>
</span></span><span style="display:flex;"><span>    usage
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">fi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> <span style="color:#f92672">[</span> $verbose <span style="color:#f92672">==</span> n <span style="color:#f92672">]</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">then</span>
</span></span><span style="display:flex;"><span>    echo <span style="color:#e6db74">&#34;Merry Christmas! </span>$name<span style="color:#e6db74">&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">else</span>
</span></span><span style="display:flex;"><span>    echo <span style="color:#e6db74">&#34;Hello, your name is </span>$name<span style="color:#e6db74">, you are </span>$age<span style="color:#e6db74"> years old!&#34;</span>
</span></span><span style="display:flex;"><span>    echo <span style="color:#e6db74">&#34;Merry Christmas!!&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">fi</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>在 <code>:vN:a:</code>中，第一个<code>:</code> 表示静默错误模式（silent error mode）。如果没有这个<code>:</code>，当遇到无效选项时，getopts 会打印错误消息。<br>
选项后的 <code>:</code>（如 N:）表示该选项需要一个参数。<br>
如果没有 <code>:</code>，则表示该选项不需要参数。</p>
<h3 id="cron">
  <a class="anchor inpage" href="#cron">###</a>cron</h3>
<p>Cron is a job scheduling utility present in Unix like systems. You can schedule jobs to execute daily, weekly, monthly or in a specific time of the day. Automation in Linux heavily relies on cron jobs.</p>
<p>Below is the syntax to schedule crons:</p>
<details open>
    <summary>bash</summary><pre
        class="chroma codeblock"
      ><code class="language-bash" data-lang="bash"
          ><span style="display:flex;"><span><span style="color:#75715e"># Cron job example</span>
</span></span><span style="display:flex;"><span>* * * * * sh /path/to/script.sh</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Here, <code>*</code> represents minute(s) hour(s) day(s) month(s) weekday(s), respectively.</p>
<p>Below are some examples of scheduling cron jobs.</p>
<table>
  <thead>
      <tr>
          <th>SCHEDULE</th>
          <th>SCHEDULED VALUE</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>5 0 * 8 *</td>
          <td>At 00:05 in August.</td>
      </tr>
      <tr>
          <td>5 4 * * 6</td>
          <td>At 04:05 on Saturday.</td>
      </tr>
      <tr>
          <td>0 22 * * 1-5</td>
          <td>At 22:00 on every day-of-week from Monday through Friday.</td>
      </tr>
  </tbody>
</table>
<p><code>crontab -l</code> lists the already scheduled scripts for a particular user.</p>
]]></content:encoded></item><item><title>regex</title><link>https://hiraethecho.github.io/docs/dev/regex/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><author>wyz2016zxc@outlook.com(Hiraeth)</author><guid>https://hiraethecho.github.io/docs/dev/regex/</guid><description>&lt;h1 id="regex"&gt;
&lt;a class="anchor inpage" href="#regex"&gt;#&lt;/a&gt;regex&lt;/h1&gt;
&lt;h2 id="vim"&gt;
&lt;a class="anchor inpage" href="#vim"&gt;##&lt;/a&gt;vim&lt;/h2&gt;
&lt;details open&gt;
&lt;summary&gt;vim&lt;/summary&gt;&lt;pre
class="chroma codeblock"
&gt;&lt;code class="language-vim" data-lang="vim"
&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;/^&lt;span style="color:#a6e22e"&gt;hello&lt;/span&gt;\&amp;gt; &lt;span style="color:#75715e"&gt;&amp;#34; 匹配行首的单词 hello&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;:%&lt;span style="color:#a6e22e"&gt;s&lt;/span&gt;&lt;span style="color:#e6db74"&gt;/foo/&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;bar&lt;/span&gt;/&lt;span style="color:#a6e22e"&gt;g&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;#34; 全局替换 foo 为 bar&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;:%&lt;span style="color:#a6e22e"&gt;s&lt;/span&gt;&lt;span style="color:#e6db74"&gt;/\(\d\+\)/&lt;/span&gt;[\&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;]/&lt;span style="color:#a6e22e"&gt;g&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;#34; 将所有数字用 [] 包裹（捕获组）&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code
&gt;&lt;button onclick="copyCode(this)" class="copybtn"&gt;copy&lt;/button&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;script&gt;
function copyCode(btn) {
const code = btn.previousElementSibling.textContent.trim();
navigator.clipboard.writeText(code).then(() =&gt; {
btn.innerText = "copied";
setTimeout(() =&gt; (btn.innerText = "copy"), 2000);
});
}
&lt;/script&gt;&lt;p&gt;捕获组：&lt;code&gt;:%s/\(\d\+\)/[\1]/g&lt;/code&gt; 将所有数字用 &lt;code&gt;[]&lt;/code&gt; 包裹（捕获组）&lt;/p&gt;</description></item></channel></rss>