shell环境操作技巧

在shell环境提取书签文件中某一链接的技巧

1
  cat bookmarks_2023_7_12.html | grep "emacs" | grep "https" | awk '{print $2}' | tr '"' ' ' | awk '{print $2}'

使某命令在后台运行的方法,但是我没有感受到效果

1
2
3
4
  if [[ "$@" == *"syncthing"* ]];
  then
  nohup "$@" &
  fi

查找某项目所有文件包含的头文件并排序去重

1
2
  grep --color=auto -rain "#include" ./ | tr ':' ' ' | awk '{print $4}' | sort | uniq
  ;; 如果要查看有多少个结果,可以在上面命令的最后以管道的形式加上 wc -l

linux如何只复制目录结构而不复制数据

1
  find ./ -type d | xargs tar -cvf anna.tar --no-recursion

将目录结构压缩到指定目录,然后手动解压即可得到目录结构

"–no-recursion"表示不递归

find + grep 查找关键词

这个命令是在当前目录及其子目录中查找所有扩展名为 .h 或 .cpp 的文件,并在找到的文件中搜索包含 "sigToTh" 的内容

1
  find ./ -name "*.cpp" -o -name "*.h" | xargs grep --color=auto -rwin "keyword"

查看Zynq各工程版本的命令

1
  find ./ -maxdepth 2 -name "*.xpr" | xargs head -5

linux命令将"./"替换为空格

1
  find ./ -maxdepth 1 -type f | sed -e 's/\.\//\ /g'

linux命令将"./"删除

在sed命令中,替换操作的分隔符可以使用除了反斜杠 (\)、换行符以及所选字符之一以外的任何字符。在上面的命令中,我们使用了竖线 (|) 作为分隔符,因为这个字符不太可能出现在文件路径中,以避免干扰正则表达式的匹配。

在sed命令中,也可以使用斜杠 (/) 作为分隔符。但是,在本例中,文件路径中包含斜杠字符,会引起匹配错误。因此,我们选择使用竖线作为分隔符。

在sed命令中,正则表达式和替换字符串之间用分隔符分隔开来。因为我们使用的是竖线作为分隔符,所以需要在每个竖线字符前后都加上一个竖线字符,即 "s|pattern|replacement|"。

最终,两个竖线字符 (||) 表示空字符串,用于替换字符串为空。在这个命令中,我们使用sed命令将文件路径中开头的 "./" 删除,如下所示:

其中,"^\\./"表示以 "./" 开头的字符串,"|" 是分隔符,"" 表示替换为空字符串。

1
  find ./ -maxdepth 1 -type f | sed -e 's|^\./||'

查找文件并高亮显示

1
  find ./ -name "stm32*" | grep --color "."

linux查看cpu核数

1
  cat /proc/cpuinfo | grep -w "cpu cores" | head -1 | awk '{print $4}'

通过find查找文件和通过grep查找关键词并排除进制文件

排除二进制文件:–binary-files=without-match

1
  find ./ -type f | xargs grep --color --binary-files=without-match -n "sit0"

通过find查找最近一天的文件,通过grep命令匹配当天的文件

1
2
  work_dir=${USER}
  alias cr='clear && clear && find ${HOME}/${work_dir}/reports/*.txt -mtime -1 | xargs cat | grep -A 100 "$(date -I | sed -e 's/-//g')"'

在Shell脚本中,单个等号 `=` 和双等号 `==` 在条件判断时有一些区别

  1. 单个等号 =

    • 在条件判断中,单个等号用于判断字符串是否相等。
    • 用法示例:[ "$var" = "value" ],表示变量 $var 的值是否等于字符串 "value"。
  2. 双等号 ==

    • 在条件判断中,双等号也用于判断字符串是否相等,但是推荐在 Bash 中使用双等号进行字符串比较。
    • 用法示例: "$var" == "value" ,表示变量 $var 的值是否等于字符串 "value"。

主要区别在于:

  • 单个等号 = 可以在绝大多数的Shell中使用,而双等号 == 是Bash特有的语法。
  • 双等号 == 支持更多高级的模式匹配功能,例如正则表达式匹配。

总的来说,在Bash脚本中推荐使用双等号 == 来进行字符串比较,更加灵活且符合习惯。如果你不确定当前环境是否支持双等号 ==,可以使用单个等号 = 来进行字符串比较。

处理 URL 中获取的变量的乱码

例如变量 cfv 打印到终端上的是"v2.2.5",但是在用 wget 下载的时候,链接中 cfv 的值就变成了"v2.2.5%0D"这是为什么呢

在这样的情况下,出现链接中包含了 %0D 的原因可能是因为在获取 cfv 变量的过程中,字符串结尾包含了回车符(Carriage Return)。

回车符通常用 \r 表示,在 URL 中,\r 会被转义成 %0D。这可能是由于在从网页内容中提取 cfv 变量时,结尾包含了回车符导致的。在处理字符串时,特别是从网页内容中提取的字符串,需要格外注意是否包含了不可见的控制字符,如回车符或换行符。

为了解决这个问题,可以在提取 cfv 变量后,对其进行处理以去除结尾的回车符或其他不可见字符。在 Bash 脚本中,可以使用 sed 命令来去除结尾的回车符,例如:

1
  cfv=$(echo $cfv | sed 's/\r//g')

这样处理后,cfv 变量中就不会包含回车符,从而避免在 URL 中出现 %0D 的情况。

shell位运算,左移,右移,与运算,进制转换

进行移位运算

左移29位,以十六进制输出

1
  a=$((0x1<<29)); printf "0x%04X" $a

进行与运算

1
  a=$((0x03&0x07)); printf "0x%X" $a

进行或运算

1
  a=$((0x03|0x07)); printf "0x%X" $a

如何用shell脚本实现回车继续

在 Bash 脚本中,你可以使用 read 命令来等待用户按下回车键继续执行脚本。下面是一个简单的示例:

1
2
3
4
5
6
7
  #!/bin/bash

  # 显示提示信息
  echo "按下回车键继续..."

  # 读取用户输入(等待用户按下回车键)
  read -p "(按下回车键继续)" continue

在这个示例中,read -p "(按下回车键继续)" continue 会等待用户按下回车键,并且在用户按下回车键之后继续执行脚本。

当脚本执行到这一行时,它会暂停等待用户输入。用户按下回车键之后,脚本会继续执行后面的命令。

你也可以根据自己的需求修改提示信息和变量名。这样的代码片段可以用于需要用户确认或者暂停执行的情况。

shell 如何只刷新当前行

在 shell 中,要实现只刷新当前行而不换行,可以使用 ANSI 控制码 \r。这个控制码会将光标移动到当前行的开头,然后你可以输出新的内容,从而实现只刷新当前行而不换行。示例代码如下:

1
2
3
4
5
6
7
8
  #!/usr/bin/bash

  echo -n "Loading: 10%"
  sleep 1
  echo -en "\rLoading: 20%"
  sleep 1
  echo -en "\rLoading: 30%"
  # 以此类推

在这个例子中,-n 参数用于禁止echo命令自动换行,而\r用于将光标移动到行首,然后输出新的内容,实现了只刷新当前行的效果。

在 Bash 中,-e 选项用于启用反斜杠转义(enable escape characters),它允许 echo 命令解释特定的转义序列。

具体来说,当你在 echo 命令中使用 -e 选项时,可以在输出中使用以下特殊的转义序列:

  • \n:换行
  • \t:制表符
  • \r:回车
  • \\:反斜杠

举个例子,如果你想在输出中包含一个换行符,你可以这样使用 -e 选项:

1
  echo -e "Hello\nWorld"

这将会输出以下内容:

1
2
  Hello
  World

如果不使用 -e 选项,\n 将会被当作普通字符输出,而不会被解释为换行符。

shell 通过只刷新当前行显示时间

1
2
  $ while true; do echo -en "\r\e[34m$(date)\e[0m"; sleep 1; done
  2024年03月18日 11:10:40

显示 grep 匹配关键词之前或之后指定行数

显示 grep 匹配关键词之前指定行数

1
  grep "MODULE_LICENSE" -B 27 /usr/src/linux-headers-`uname -r`/include/linux/module.h

显示 grep 匹配关键词之后指定行数

1
  grep "MODULE_LICENSE" -A 27 /usr/src/linux-headers-`uname -r`/include/linux/module.h

Ubuntu 匹配 IP 地址

只打印匹配到的内容,不打印多余的内容

如果您需要提取出 IP 地址,可以使用正则表达式来匹配并提取 IP 地址。以下是一个示例命令,可以从文本中提取出 IP 地址:

1
  ifconfig | grep -w -A 1 "br0" | grep -v "br0" | awk '$1=="inet" {print $2}' | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b"

在这个命令中,我们使用了 grep -oE 结合正则表达式 \b([0-9]{1,3}\.){3}[0-9]{1,3}\b 来提取文本中的 IP 地址。这个正则表达式可以匹配标准的 IPv4 地址格式。

当处理 IP 地址时,常见的 IPv4 地址由四个小节组成,每个小节是 0 到 255 之间的数字。在正则表达式中,可以使用以下模式来匹配一个标准的 IPv4 地址:

  • \b:表示单词边界,用于确保匹配的是完整的 IP 地址而不是部分匹配。
  • ([0-9]{1,3}\.){3}:匹配三个由数字组成的小节,每个小节包含 1 到 3 个数字({1,3} 表示重复 1 到 3 次),并且每个小节之间用点号分隔。
  • [0-9]{1,3}:匹配最后一个小节,同样包含 1 到 3 个数字。
  • \b:再次使用单词边界,以确保 IP 地址的结尾是一个单词边界。

因此,这个正则表达式 \b([0-9]{1,3}\.){3}[0-9]{1,3}\b 可以准确地匹配一个标准的 IPv4 地址格式。

在命令中使用 grep -oE 来执行正则表达式匹配操作,-o 选项表示只输出匹配到的部分,-E 表示使用扩展的正则表达式语法。

shell脚本如何创建数组或列表

在 shell 脚本中,您可以使用类似以下的语法来创建数组:

1
2
3
4
5
6
7
  # 创建一个包含多个元素的数组
  my_array=(element1 element2 element3)

  # 或者逐个添加元素到数组中
  my_array[0]=element1
  my_array[1]=element2
  my_array[2]=element3

另外,您也可以使用 declare 命令来声明一个数组:

1
2
  declare -a my_array
  my_array=(element1 element2 element3)

要访问数组中的元素,可以使用下标来引用:

1
2
3
4
5
6
  echo ${my_array[0]}  # 输出第一个元素
  echo ${my_array[1]}  # 输出第二个元素
  echo ${my_array[2]}  # 输出第三个元素

  # 输出整个数组
  echo ${my_array[@]}

除了数组,您也可以使用空格分隔的列表,如下所示:

1
  my_list="item1 item2 item3"

然后,您可以使用变量来引用整个列表或者单独的元素:

1
2
  echo $my_list   # 输出整个列表
  echo $my_list   # 输出第一个元素

这是在 shell 脚本中创建数组和列表的简单方法。根据您的需求选择合适的数据结构来存储元素。

如何自动获取数组个数

在 shell 脚本中,您可以使用 ${#array[@]} 来获取数组中元素的个数。以下是一个示例:

1
2
3
4
5
6
7
8
  # 创建一个包含多个元素的数组
  my_array=(element1 element2 element3)

  # 获取数组中元素的个数
  array_length=${#my_array[@]}

  # 输出数组中元素的个数
  echo "数组中元素的个数为: $array_length"

通过 ${#my_array[@]},您可以轻松地获取数组 my_array 中元素的个数,并将其存储在变量 array_length 中以供后续使用。

如果您需要获取列表的元素个数,可以使用类似的方法:

1
2
3
4
5
6
7
8
9
  # 创建一个空格分隔的列表
  my_list="item1 item2 item3"

  # 将列表转换为数组(以便使用相同的方式获取元素个数)
  list_array=($my_list)
  list_length=${#list_array[@]}

  # 输出列表中元素的个数
  echo "列表中元素的个数为: $list_length"

这样就可以自动获取数组和列表中元素的个数,方便您在脚本中进行后续处理。

如何找到文件安装位置

要找到软件包的安装位置,可以使用 dpkg 命令来查询已安装软件包的安装信息。以下是一些常用的命令和选项:

  1. 列出所有已安装的软件包及其安装路径:
1
dpkg -l

这条命令会列出系统上所有已安装的软件包以及它们的版本号、描述等信息,其中包含了软件包的安装路径。

  1. 查询特定软件包的安装路径:
1
dpkg -L package_name

将 package_name 替换为你想要查询的软件包名称,这条命令会列出指定软件包的安装路径。

  1. 查询文件属于哪个软件包:
1
dpkg -S /path/to/file

将 /path/to/file 替换为你想要查询的文件路径,这条命令会告诉你该文件属于哪个软件包。

  1. 要获取软件包的精确安装路径,可以使用以下命令来查询软件包的安装位置:
1
dpkg-query -L package_name

将 package_name 替换为你想要查询的软件包名称。这条命令会列出指定软件包的安装路径,包括所有安装文件和目录的详细路径信息。

如何将多行数据存储到数组中

你可以使用循环来逐行读取并存储到数组中。在Bash中,可以按照以下方式操作:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
  # 初始化一个空数组
  myArray=()

  # 使用循环逐行读取数据并存储到数组中
  while IFS= read -r line; do
	  myArray+=("$line")  # 将每行数据添加到数组中
  done < <(find ./ -name '*.org' -exec head -n 5 {} \; | grep -w "^date:")

  # 打印整个数组
  printf '%s\n' "${myArray[@]}"

这段代码会从find命令和grep命令中获取多行数据,并逐行存储到名为myArray的数组中。最后,通过 printf 将整个数组打印出来。

在 Bash 中,IFS(Internal Field Separator)是一个特殊的环境变量,用于指定字段的分隔符,默认情况下包含空格、制表符和换行符。当对 IFS 进行设置时,会影响到后续命令中对字段的解析方式,例如 read 命令。

在 Bash 的 read 命令中,-r 和 -a 都是选项(或称为标志),用于对输入进行处理和赋值。它们的作用如下:

  1. -r 选项:

    • 当使用 -r 选项时,read 命令会禁用反斜杠转义。这意味着如果输入中包含反斜杠字符 \,它不会被特殊对待,而是按照原样赋值给变量。通常情况下,建议在使用 read 命令时始终加上 -r 选项,以避免意外的反斜杠转义。
  2. -a 选项:

    • 当使用 -a 选项时,read 命令会将读取的输入赋值给指定的数组变量,而不是普通的字符串变量。这样可以方便地将输入按照特定的分隔符(如空格)分割成多个部分,并存储到数组中的各个元素中。

因此,-r 选项用于禁用反斜杠转义,而 -a 选项用于将输入赋值给数组变量。

在终端执行示例-1

查找"*.org"文件并存入数组,然后打印数组第一个元素到终端验证效果

1
  mapfile -t file_array < <(find ./ -name "*.org" -type f -exec readlink -f {} +); echo ${file_array[0]}

在终端执行示例-2

该示例在vivado工程包含sdk应用程序的条件下,查找sdk工程中的.mss文件,然后去搜索zynq芯片ps端的配置是否存在,从而确认ps端的配置情况

1
  mapfile -t file_array < <(find ./ -name "*.mss" -type f); for i in "${file_array[@]}"; do echo -e "\n"; grep --color=always -Hn "psu_uart" "${i}"; done

查看文件创建时间,并把创建时间组成使用hugo命令创建博客时生成的时间戳:

以 ssh配置.org 为例,查看该文件的创建时间,然后组成时间戳

1
   target="ssh配置.org"; fileCreateTime="date: $(stat ${target} | tail -n 1 | grep -Eo "\b[0-9]{4}-[0-9]{2}-[0-9]{2}\b")T$(stat ${target} | tail -n 1 | grep -Eo "\b[0-9]{2}:[0-9]{2}:[0-9]{2}\b")+08:00"; echo ${fileCreateTime}

运行后,打印如下时间戳

1
  date: 2024-03-26T00:24:29+08:00

在 awk 中,可以使用字符串连接符来连接多个关键词或字段

你可以使用逗号 , 来连接多个字段或字符串,并通过空格或其他字符来分隔它们。下面是一个示例,演示了如何在 awk 中连接多个关键词:

假设我们有一个名为 data.txt 的文本文件,内容如下:

1
2
3
4
5
Alice 25
Bob 30
Charlie 27
David 22
Eve 35

现在假设我们想要使用 awk 命令来输出年龄大于 25 的人的姓名和年龄,并在输出时添加一些额外的描述性文字。我们可以这样做:

1
  awk '$2 > 25 {print "Name: " $1 ", Age: " $2}' data.txt

这个命令的含义是,对于每一行数据,如果第二列(年龄)大于 25,则输出 "Name: "、姓名、", Age: "、年龄。运行这个命令后,输出将会是:

1
2
3
Name: Bob, Age: 30
Name: Charlie, Age: 27
Name: Eve, Age: 35

在这个示例中,我们使用了字符串连接符 , 来连接固定的文字和字段,以便形成输出的完整描述。你可以根据自己的需求使用不同的连接方式和格式来构建输出。

要使用 AWK 输出指定行

你可以结合 AWK 的条件判断功能来实现。以下是一个简单的示例:

假设有一个名为 example.txt 的文本文件,内容如下:

#+end_src Line 1: This is the first line Line 2: This is the second line Line 3: This is the third line Line 4: This is the fourth line Line 5: This is the fifth line

#+end_src

如果要输出第3行的内容,可以使用以下命令:

1
  awk 'NR==3' example.txt

这行命令中,NR==3 表示当前行号等于3时执行相应操作,example.txt 是输入文件。

如果要输出多行(比如输出第2行到第4行的内容),可以使用类似的方式:

1
  awk 'NR>=2 && NR<=4' example.txt

这样会输出第2行到第4行的内容。

hugo 批量插入文件的 Linux 脚本参考

1
  find ./ -type f | xargs readlink -f| awk -F '/' '{print "[[/"$8"/"$9"/"$10"/"$11"/"$12"]["$12"]]"}'

批量创建文件并添加指定内容到文件中

1
  for i in {1..5}; do touch $i.org; echo -e "1\n2\n3\n4\n5\n" >> $i.org; done

如果您想要使用 grep 命令从文件中的指定范围检索内容,可以结合使用 head 和 tail 命令来实现。下面是一个示例:

假设您想在文件 example.txt 的第 10 行到第 20 行之间检索包含特定内容的行,可以按照以下步骤进行:

1
  head -n 20 example.txt | tail -n +10 | grep "要查找的内容"

这个命令的含义是先使用 head 命令获取文件前 20 行,然后再通过 tail 命令取其中的第 10 行到最后一行,最后使用 grep 命令在这个范围内查找包含特定内容的行。

请将上述命令中的 "要查找的内容" 替换为您需要查找的实际内容。

想办法将文件存入数组

将文件存入数组,然后查看数组成员个数,再将数组的第四个成员值打印出来

1
  mapfile -t file_array < <(find ./ -name "*.org" -type f -exec readlink -f {} +); echo "${#file_array[@]}"; echo "${file_array[3]}";

mapfile 是一个 Bash 内置命令,用于将输入按行分割并存储到数组中。

具体来说,mapfile 命令会从标准输入中读取数据,并将每一行作为数组的一个元素存储起来。这在处理文本文件、命令输出或其他需要按行进行处理的情况下非常有用。

Here 文档(<<)是用来输入多行字符串的,而不是用来处理命令替换的。

以下是 mapfile 命令的一般语法:

bash mapfile [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] array

  • -n count:指定要读取的行数。
  • -O origin:从数组的哪个索引位置开始存储数据。
  • -s count:跳过输入的前几行。
  • -t:去掉每个元素末尾的换行符。
  • -u fd:从指定文件描述符读取输入。
  • -C callback:对每个读取的行调用一个回调函数进行处理。

使用 mapfile 命令可以简化将文本文件内容读入数组的过程,同时避免了使用循环逐行读取的繁琐操作。

总之,mapfile 命令的作用是将输入按行分割并存储到数组中,为处理大量文本数据提供了便利的方法。

sftp 批量执行命令教程

通过以下方式批量执行命令

1
2
3
4
  sftp ssh << __EOF__
  cd /
  ls
  __EOF__

sftp 批量执行命令教程-示例

将运行命令粘贴到终端并回车直接运行,也可以以脚本的形式运行

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
  $ sftp sdf << __EOF__
  cd /
  ls
  __EOF__
  Connected to sdf.
  sftp> cd /
  sftp> ls
  arpa         bin          boot         boot.cfg     com          dev
  etc          ftp          lib          libdata      libexec      lost+found
  mail         mnt          netbsd       proc         sbin         sdf
  stand        sys          tmp          udd          usr          var
  www

expect

1.用expect实现与shell交互,用ssh连接termxu实例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
  #!/usr/bin/expect       #这一句为声明,声明的方式为`#` + `!` + `expect路径`果不知道expectr的路径,可以执行`which expect`来查看
  set host "192.168.0.0"  #非本人ip,随便编的ip地址
  set password "123456"
  spawn ssh -p 8022 $host
  expect 
  {

	  "*yes/no*\r"    #如果检测到包含部分字符串,输出内容与shell交互
	  {
		  send "yes\r"
	  }

	  "*assword:"
	  {
		  send "$password\r"
	  }

  }
  interact       #连接后保持连接状态

2.用 expect 登录 termux 并执行脚本实例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
  #!/usr/bin/expect
  set host "192.168.0.0"
  set password "..Qq1ssh.."
  set script "touch 54545455454545454544545545445455545454454454.sh" #假设脚本内容只是创建一个文件
  spawn ssh -p 8022 $host
  expect {
	  "*yes/no*\r"
	  {
		  send "yes\r"
	  }
	  "*assword:"
	  {
		  send "$password\r"
	  }
  }
  • expect "*" #匹配到任意字符
  • send "$script\r" #执行脚本
  • expect "*" #匹配到任意内容
  • send "exit\r" #退出
  • send "\r" #换行
  • expect eof #执行完后退出

3. expect eof 与 interact 的区别:

这两个命令作为结束语句用的,如果只是执行一次任务就退出,那么可以用expect eof,如果连接后想要保持连接状态,那么就用interact

4.注意事项:

有一点需要注意,执行脚本的方式有很多种,但是执行expect脚本的时候只能用 expect ./ 的方式执行,目前我知道的两种方式,不然会执行失败。

如何使用wget下载整个网站

wget 是用于从网站下载资源的 linux 命令,基本用法是 wget url:

1
  wget http://www.w3schools.com/

一般来说,网站的页面会有很多链接,点击之后可以链接到其他页面,其他页面也可能有链接,就这样一级一级链接下去,如果要把这些所有关联的页面都下载下来,用法是:

1
  wget -r http://www.w3schools.com/

但是大部分网站不允许你下载所有网站的内容,如果网站检测不到浏览器标识,会拒绝你的下载连接或者给你发送回一个空白网页。这个时候在 wget 后面加上 user-agent 就可以:

1
  wget -r -p -U Mozilla http://www.w3schools.com/

为了避免被网站加入黑名单,我们可以限制下载的速度以及两次下载之间的等待时间:

1
  wget --wait=20 --limit-rate=20K -r -p -U Mozilla http://www.w3schools.com/

如何只是想下载特定文件夹下的网页,使用 –no-parent 只下载 /js 下的所有页面

1
  wget --wait=20 --limit-rate=20K --no-parent -r -p -U Mozilla http://www.w3schools.com/js/default.asp

cat命令

1
2
  cat a > b #将a中文件覆盖到文件b中
  cat a >> b #将a中文件追加到文件b中

在SSH命令中,使用-D参数来创建动态端口转发时

不需要指定本地地址。正确的用法是只指定端口号,例如:

1
ssh -D 1080 root@segfault.net

这将在本地主机上创建一个SOCKS代理,监听在端口1080上,并将流量通过SSH通道转发到远程主机segfault.net。在这个命令中,root是远程主机的用户名,segfault.net是远程主机的地址。

find命令查找并复制文件到指定路径

提取视频到“视频提取”这个目录中

1
  find ./ -name "*.mp4" -type f -exec cp '{}' 视频提取 \;

ffmpeg-ffplay自动播放视频列表

将当前中路径下的视频文件名称保存到数组中,然后通过for循环和ffplay依次播放数组中的文件

1
  mapfile -t file_array < <(ls | sort); for i in "${file_array[@]}"; do ffplay -autoexit "${i}"; done

查找文件并进行排序

1
  find ./ -type f -exec ls -l --time-style=+%s {} \; | sort -k6n | awk '{print $1, $2, $3, $4, $5, strftime("%Y-%m-%d %H:%M:%S", $6), $7, $8, $9, $10}'

这个命令是一个复杂的管道命令,它主要用于列出当前目录及其子目录中所有文件的详细信息,并按文件修改时间进行排序。让我们一步步拆解这个命令:

  1. find ./ -type f -exec ls -l –time-style=+%s {} \;:

    • find ./ -type f:使用 find 命令查找当前目录 (./) 及其子目录中的所有文件 (-type f)。
    • -exec ls -l –time-style=+%s {} \;:对于找到的每一个文件,执行 ls -l 命令来显示详细信息,并使用 –time-style=+%s 选项以秒数的形式显示修改时间。
  2. sort -k6n:

    • sort 命令用于排序输入的行。
    • -k6n:指定排序的关键字为第6列(修改时间),并使用数字方式进行排序。
  3. awk '{print $1, $2, $3, $4, $5, strftime("%Y-%m-%d %H:%M:%S", $6), $7}':

    • awk 是一种文本处理工具,用于对文本进行逐行处理。
    • '{print $1, $2, $3, $4, $5, strftime("%Y-%m-%d %H:%M:%S", $6), $7}':对输入的每一行进行处理,打印出第1到第7列的内容,并将第6列的时间戳转换为指定格式的日期时间字符串。

综合起来,这个命令的作用是列出当前目录及其子目录中所有文件的详细信息,并按文件修改时间进行排序,最后以指定的格式输出。

在这个命令中,find 和 ls 是结合使用的,但它们的工作方式是分开的。find 命令是用来查找文件的,它会递归地遍历指定目录及其子目录,找到符合条件的文件。而 -exec ls -l –time-style=+%s {} \; 这部分则是在找到每一个文件后都会执行一次 ls -l 命令来获取文件的详细信息。

换句话说,find 命令是逐个找到文件,然后立即通过 -exec 选项将每个找到的文件传递给 ls -l 命令进行处理。这意味着,不是等到所有文件都找到后再一次性地通过 ls -l 命令处理,而是边找到文件边处理。

这样做的好处是可以实时获取每个文件的详细信息,并且可以在处理每个文件时进行额外的操作,例如这里的 –time-style=+%s 选项用来显示文件的修改时间戳。

shopt 使用技巧

Linux 环境启用 extglob 扩展

例如在 bash shell 中,rm -rf !(file) 无效,因为 !(pattern) 是 extglob 扩展,需要打开扩展模式才能使用。要配置 shopt 来启用 extglob 扩展,可以按照以下步骤进行:

  1. 打开终端。
  2. 运行 shopt -s extglob 命令来启用 extglob 扩展。
  3. 现在你应该可以使用 !(pattern) 这样的模式来排除某些文件,例如 rm -rf !(file)。

请注意,在使用 extglob 扩展时要格外小心,确保不会意外删除重要文件。

shopt -s extglob 与 shopt -u extglob 有区别吗

shopt -s extglob 和 shopt -u extglob 是 bash shell 中的两个不同命令,它们分别用于启用和禁用 extglob 扩展。这两个命令的作用如下:

  • shopt -s extglob:这个命令用于启用 extglob 扩展,允许在 bash shell 中使用扩展模式,比如 !(pattern)、*(pattern)、+(pattern)、?(pattern) 和 @(pattern)。
  • shopt -u extglob:这个命令用于禁用 extglob 扩展,即关闭扩展模式,使得在 bash shell 中不能再使用上述提到的扩展模式。

因此,这两个命令的区别在于一个用于启用扩展模式,另一个用于禁用扩展模式。

Linux 下切换目录省略 cd 命令

shopt -s autocd:启用 Bash 的 autocd 选项,使得在输入目录路径时可以省略 cd 命令,直接切换到该目录。

shell脚本如何获取参数数量

在Shell脚本中,你可以使用内置变量 $# 来获取传递给脚本或函数的参数数量。这个变量表示传递给脚本或函数的参数数量。

例如,假设你有一个名为 script.sh 的Shell脚本,可以通过 $# 来获取传递给该脚本的参数数量,如下所示:

1
2
3
  #!/bin/bash

  echo "Number of arguments: $#"

当你执行 ./script.sh arg1 arg2 arg3 时,它将输出:

1
  Number of arguments: 3

这表明传递给脚本的参数数量为3。

如何获取最后一个参数

要获取最后一个参数,你可以使用特殊变量 $ 后跟参数的索引。在 Bash 中,$# 表示参数的总数,而 ${!#} 表示最后一个参数。

如何获取多个参数的内容

要获取多个参数的内容,你可以使用 $1, $2, $3 等等来访问每个参数的值。如果你不确定要获取多少个参数,可以使用循环来处理它们。

以下是一个示例脚本,演示如何获取并打印所有参数的内容:

1
2
3
4
5
6
7
8
9
  #!/usr/bin/bash

  args="$#"

  echo "Total arguments: $args"

  for ((i = 1; i <= args; i++)); do
	  echo "Argument $i: ${!i}"
  done

当你执行 ./script.sh arg1 arg2 arg3 时,它将输出:

1
2
3
4
  Total arguments: 3
  Argument 1: arg1
  Argument 2: arg2
  Argument 3: arg3

这表明脚本正确地获取并打印了所有参数的内容。

Linux命令中短横线的作用

用以下命令举例

1
  tar -cpzf - ./ | tar -xpzf - -C dir

这个命令可以分解为两个部分:

  1. tar -cpzf - ./:这部分将当前目录中的所有文件和子目录打包成一个tar文件,并通过标准输出(stdout)输出。 -c 表示创建归档文件,-p 保留文件权限和属性,-z 使用gzip进行压缩,-f - 将归档文件输出到标准输出。
  2. tar -xpzf - -C dir:这部分将从标准输入(stdin)读取tar文件,并将其解压缩到指定的目录。-x 表示提取文件,-p 保留文件权限和属性,-z 使用gzip进行解压缩,-f - 从标准输入读取归档文件,-C dir表示将文件提取到指定的目录。

综合起来,整个命令的作用是将当前目录中的所有文件和子目录打包成一个tar文件,并通过管道传输给另一个命令,该命令将tar文件解压缩到指定的目录(dir)。这样就实现了将当前目录中的文件和子目录传输到指定目录并进行解压缩的操作。

Linux下如何查看当前用的是zsh还是bash

要查看当前正在使用的是 zsh 还是 bash,可以使用以下命令:

1
  echo $SHELL

这个命令会输出当前 shell 的路径。通常情况下,如果你的 shell 是 bash,它会输出 /bin/bash;如果是 zsh,它会输出 /bin/zsh。

通过lshw命令确定系统是否支持 ECC 内存

使用 lshw 命令: lshw 是一个用于列出系统硬件信息的工具,可以使用它来查看系统的内存信息,包括 ECC 支持情况。运行以下命令:

1
  sudo lshw -class memory | grep -i ecc

linux如何查看内存大小

在Linux系统中,有多种方式可以查看系统内存大小。以下是几种常用的方法:

  1. 使用free命令

free命令可以查看系统内存的总量、使用量和空闲量等信息。在终端中输入以下命令即可查看:

1
  free -h

该命令会以人类可读的方式显示内存信息,例如:

1
2
3
  total        used        free      shared  buff/cache   available
  Mem:           7.7G        2.4G        1.1G        1.1G        4.2G        4.3G
  Swap:          2.0G          0B        2.0G

其中,total表示内存总量,used表示已使用的内存量,free表示空闲的内存量。

  1. 使用cat命令

/proc/meminfo文件包含了系统内存的详细信息。您可以使用cat命令查看该文件的内容,如下所示:

1
  cat /proc/meminfo

该命令会输出系统内存的详细信息,例如

1
2
3
4
5
6
7
8
  MemTotal:        8051920 kB
  MemFree:         1172128 kB
  MemAvailable:    4458368 kB
  Buffers:          125528 kB
  Cached:          4023852 kB
  SwapCached:            0 kB
  Active:          2927372 kB
  Inactive:        2965436 kB

其中,MemTotal表示内存总量,以千字节为单位。

  1. 使用dmidecode命令

dmidecode命令可以显示系统硬件信息,包括内存信息。在终端中输入以下命令即可查看:

1
  sudo dmidecode -t memory

该命令会输出系统中所有内存模块的详细信息,例如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
  # dmidecode 3.2
  Getting SMBIOS data from sysfs.
  SMBIOS 2.7 present.

  Handle 0x1000, DMI type 16, 23 bytes
  Physical Memory Array
  Location: System Board Or Motherboard
  Use: System Memory
  Error Correction Type: None
  Maximum Capacity: 32 GB
  Error Information Handle: Not Provided
  Number Of Devices: 4

  Handle 0x1100, DMI type 17, 34 bytes
  Memory Device
  Array Handle: 0x1000
  Error Information Handle: Not Provided
  Total Width: 64 bits
  Data Width: 64 bits
  Size: 8192 MB
  Form Factor: DIMM
  Set: None
  Locator: ChannelA-DIMM0
  Bank Locator: BANK 0
  Type: DDR3
  Type Detail: Synchronous
  Speed: 1600 MT/s
  Manufacturer: Kingston
  Serial Number: 123456789
  Asset Tag: Not Specified
  Part Number: KHX1600C9D3K2/8GX
  Rank: 2
  Configured Clock Speed: 1600 MT/s
  Minimum Voltage: 1.5 V
  Maximum Voltage: 1.5 V
  Configured Voltage: 1.5 V

其中,Maximum Capacity表示内存总量,以GB为单位。

使用 dd 命令来测试硬盘的写入速度,并且采用一些优化参数来减少系统缓存的影响

示例

1
2
3
4
5
6
7
8
  $ time dd if=/dev/zero of=/testw.dbf bs=1M count=1000 oflag=direct
  记录了1000+0 的读入
  记录了1000+0 的写出
  1048576000字节(1.0 GB,1000 MiB)已复制,6.8299 s,154 MB/s

  real    0m6.876s
  user    0m0.046s
  sys     0m0.108s
  1. time dd if=/dev/zero of=/testw.dbf bs=1M count=1000 oflag=direct:

    • time:用于测量命令执行的时间。
    • dd:数据传输命令。
    • if=/dev/zero:输入文件指定为 /dev/zero,该文件会产生无限的零字节流。
    • of=/testw.dbf:输出文件指定为 /testw.dbf,这是测试中要写入的文件。
    • bs=1M:块大小设置为 1 MB,表示每次读取或写入的数据块大小为 1 MB。
    • count=1000:指定了写入的块数为 1000,因此总共要写入 1000 × 1 MB = 1000 MB 的数据。
    • oflag=direct:该参数指示 dd 命令在执行时绕过系统缓存,直接与硬盘进行数据交换。
  2. 记录了1000+0 的读入:表示成功读取了 1000 个数据块。
  3. 记录了1000+0 的写出:表示成功写入了 1000 个数据块。
  4. 1048576000字节(1.0 GB,1000 MiB)已复制,6.8299 s,154 MB/s:

    • 表示总共复制了 1,048,576,000 字节,即 1.0 GB 的数据。
    • 6.8299 s 是命令执行的实际时间。
    • 154 MB/s 是写入速度,即每秒写入 154 MB 的数据量。
  5. real 0m6.876s:实际时间,即命令的总执行时间。
  6. user 0m0.046s:用户 CPU 时间,即命令在用户态消耗的 CPU 时间。
  7. sys 0m0.108s:系统 CPU 时间,即命令在内核态消耗的 CPU 时间。

综合来看,该命令测试了硬盘的写入速度,并显示了每秒写入的数据量为 154 MB,这是在绕过系统缓存的情况下测得的结果。

xxd使用技巧

将文本转换为ASCII对应的16进制输出

操作命令

1
  echo '0' | xxd -p

使用实例

结果用ASCII表示,30表示字符0,0a表示换行符

1
2
  $ echo '0' | xxd -p
  300a

将ASCII对应的16进制转换为ASCII输出

操作命令

1
  echo '300a' | xxd -r -p

使用实例

1
2
  $ echo '300a' | xxd -r -p
  0

linux环境如何合并两个文件夹,两个目录名相同,文件有相同的也有不相同的,遇到同名文件跳过

在 Linux 环境中,你可以使用 rsync 命令来合并两个文件夹,并在遇到同名文件时跳过。rsync 是一个强大的文件同步工具,可以用于在本地或远程系统之间同步文件和目录。

以下是使用 rsync 命令合并两个目录的基本语法:

1
  rsync -av --ignore-existing 源目录/ 目标目录/

这里的参数含义如下:

  • -a, –archive:以归档模式进行同步,包括递归地复制子目录、保持文件权限、保持文件修改时间等。
  • -v, –verbose:显示详细的输出信息,让你知道正在发生什么。
  • –ignore-existing:忽略已经存在于目标目录中的文件,不进行覆盖,这样就能实现遇到同名文件时跳过的效果。
  • 源目录/:指定源目录的路径。
  • 目标目录/:指定目标目录的路径。

例如,假设你有两个目录 folder1 和 folder2,你想将它们合并到一个目录 merged_folder 中,可以使用以下命令:

1
2
  rsync -av --ignore-existing folder1/ merged_folder/
  rsync -av --ignore-existing folder2/ merged_folder/

这样就会将 folder1 和 folder2 中的文件合并到 merged_folder 中,并在遇到同名文件时跳过。

Linux history 命令详解:如何查看、显示时间、清空、重复和控制历史记录

当然,让我们详细解释 history 命令的各个方面:

### 1. 查看历史记录

使用 history 命令可以查看 Bash shell 中执行过的命令历史记录。这将显示按照执行顺序排列的历史记录列表,每个命令前面带有一个数字。

### 2. 显示时间戳

默认情况下,history 命令不会显示每个命令执行的时间戳。但是,你可以通过设置 HISTTIMEFORMAT 环境变量来显示时间戳。例如:

1
export HISTTIMEFORMAT="%F %T "

这将在历史记录中显示日期和时间。

### 3. 清空历史记录

要清空 Bash shell 中的命令历史记录,可以使用 history -c 命令:

1
history -c

这将删除当前会话中的所有历史记录。要永久删除历史记录,可以编辑或者删除历史记录文件,通常是 ~/.bash_history。

### 4. 重复执行历史命令

要重复执行历史记录中的命令,可以使用 ! 后跟命令的历史编号。例如,要重新执行历史记录中编号为 123 的命令:

1
!123

你还可以使用 !! 来重复执行上一条命令。

### 5. 控制历史记录

你可以使用 HISTSIZE 和 HISTFILESIZE 环境变量来控制历史记录的大小。HISTSIZE 定义了保存在内存中的历史记录数目,HISTFILESIZE 定义了保存在历史记录文件中的历史记录数目。如果 HISTFILESIZE 比 HISTSIZE 小,那么当 shell 退出时,会将 HISTSIZE 指定的数量的命令写入历史记录文件中。

Linux终端打印如何删除指定列或多列

要删除Linux终端中的指定列或多列,你可以使用一些命令和技巧。以下是几种方法:

  1. 使用awk命令删除指定列: 如果你知道要删除的列的位置,你可以使用awk命令来实现。例如,如果要删除第3列,你可以使用以下命令:

    1
    
    awk '{$3=""; print}' input_file

    这将从input_file中删除第3列并输出结果。你还可以使用逗号分隔多个列的位置,例如:

    1
    
    awk '{$2=""; $4=""; print}' input_file

    这将删除第2列和第4列,并输出结果。

  2. 使用cut命令删除指定列: 如果你知道要删除的列的位置,你也可以使用cut命令。例如,如果要删除第3列,你可以使用以下命令:

    1
    
    cut -d' ' -f1,2,4- input_file

    这将从input_file中删除第3列并输出结果。你可以通过指定列的位置来删除多列。

这个命令是用来在Linux终端中删除指定列的。让我们一步步解析:

  • cut:这是用于剪切文本的命令。
  • -d' ':这个选项指定了字段的分隔符。在这里,-d 后跟着一个空格 (' ') 表示字段是以空格作为分隔符的。
  • -f1,2,4-:这个选项指定了要保留的字段。在这里,-f 表示字段,后面跟着的 1,2,4- 表示要保留第1、第2列以及第4列及之后的所有列。
  • input_file:这是要进行操作的输入文件的名称。

因此,整个命令的含义是从input_file中剪切出第1、第2、第4列及之后的所有列,并将结果输出到终端。

  1. 使用sed命令删除指定列: sed命令可以用来对文本进行替换和删除操作。例如,如果要删除第3列,你可以使用以下命令:

    1
    
    sed 's/\([^ ]* *\)\{2\}[^ ]* *//' input_file

    这将从input_file中删除第3列并输出结果。你可以通过调整正则表达式来删除多列。

shell排序,强大的sort

在Shell中,sort命令是一个强大的工具,用于对文本文件进行排序。它可以按照字母顺序或数字顺序对文件的行进行排序,并且可以根据需要进行自定义配置。

以下是一些常见用法:

  1. 按字母顺序排序:
1
  sort filename
  1. 按数字顺序排序:
1
  sort -n filename
  1. 逆序排序:
1
  sort -r filename
  1. 按照指定列排序:
1
  sort -k <column_number> filename
  1. 去重并排序:
1
  sort -u filename
  1. 将结果输出到新文件:
1
  sort input_filename > output_filename

这些只是 sort 命令的一些基本用法示例。根据你的需求,你可以结合使用不同的选项来实现各种排序操作。

当前目录下多文件根据排序顺序一对一对的依次进行比较

1
  mapfile -t files < <(ls); for((i=0; i<7; i++)); do diff "${files[i]}" "${files[i+1]}"; done

从当前目前进入到一个子目录过滤文件字符串并返回到当前目录

单次手动操作

1
  cd $(ls | awk 'NR==15'); find ./ -name "*.c" -o -name "*.h" | xargs grep --color=always -n "keyword"; cd ../

多次自动操作

1
  for ((i=15; i<21; i++)); do cd $(ls | awk "NR==${i}"); find ./ -name "*.c" -o -name "*.h" | xargs grep --color=always -n "keyword"; cd ../; done

Linux下gh批量下载github某仓库中Release所有版本文件

工具官网

https://github.com/cli/cli

查看指定仓库中的所有版本

1
  mapfile -t file_version < <(gh release list -R 201853910/VMwareWorkstation | awk '{$NF=""; print}' | sed -e 's/Latest//g' | awk '{print $NF}'); for i in "${file_version[@]}"; do echo "${i}"; sleep 1; done

下载所有版本的Release

1
  mapfile -t file_version < <(gh release list -R 201853910/VMwareWorkstation | awk '{$NF=""; print}' | sed -e 's/Latest//g' | awk '{print $NF}'); for i in "${file_version[@]}"; do gh release download "${i}" -D Vmwares/ -R 201853910/VMwareWorkstation; done

从文件列表中查找指定关键词脚本

1
  clear && mapfile -t dts < <(cat temp.txt); for i in "${dts[@]}"; do echo "${i}:"; grep --color=always -ain "hdmi" "${i}"; echo -e "\e[32m==========================================================================================\e[0m"; done

Linux 下计算圆周率

1
  time echo "scale=5000; 4*a(1)" | bc -l -q

time命令:指令执行时所消耗的时间

bc -l:设置标准数学库

bc -q:显示正常的GNU bc环境信息

查找文件关键词并替换

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
  #!/bin/bash

  # 将var2变量值替换掉var1变量值
  var1="10.8.98.80"				# 待被替换的关键词
  var2="192.168.0.64"				# 作为替换的关键词

  mapfile -t files < <(find ./ -name "*.cpp" | xargs readlink -f | xargs grep -l "${var1}") # 查找包含var1变量值的文件存入数组

  fileNum=${#files[@]}

  for ((i = 0; i < fileNum; i++)); do
	  sed -i "s/${var1}/${var2}/g" "${files[i]}" # 将var1替换为var2
  done

输出累加数+时间戳,按回车继续

1
  count=0; while true; do ((count++)); echo -en "\r\n$(date)-----\e[31m${count}\e[0m"; read -p "" continue; done

要仅查找 driver 目录下的 Pciedma_DLL.h 文件,可以使用以下 find 命令:

1
  find *SGDMA* -type d -name "driver" -exec find {} -name "Pciedma_DLL.h" \;

这个命令首先在包含 SGDMA 的目录下找到所有名为 driver 的目录,然后在这些目录中查找 Pciedma_DLL.h 文件。

Linux tar命令解压时提示时间戳异常的处理办法

方法一

1
  ta --touch -zxvf test.tar.gz

方法二

1
  tar -m -zxvf test.tar.gz

-m或–modification-time 还原文件时,不变更文件的更改时间。

Linux终端批量造数

Linux终端批量造十进制数

1
  clear && clear && for ((i = 0; i < 65536; i++)); do echo -en "${i} "; done

Linux终端批量造十六进制数

%x:小写

%X:大写

0x%04X:十六位大写,4*4=16

0x%08X:三十二位大写,8*4=32

0x%016X:六十四位大写,16*4=64,依次类推

Linux终端批量造十六进制数-16位

1
  clear && clear && for ((i = 0; i < 65536; i++)); do printf "0x%04X " $i; done

Linux终端批量造十六进制数-32位

1
  clear && clear && for ((i = 0; i < 65536; i++)); do printf "0x%08X " $i; done

Linux终端批量造十六进制数-64位

1
  clear && clear && for ((i = 0; i < 65536; i++)); do printf "0x%016X " $i; done

在Windows的文件资源管理器的地址栏使用mintty命令或者当前文件夹路径

1
  mintty -e /bin/bash -c "pwd | clip"

或者

1
  D:\cygwin\bin\mintty.exe -e /bin/bash -c "pwd | clip"

查找文件并依次进行比较

1
  mapfile -t files < <(find ./ -name "M6678_SRIO.h"); for ((i = 0; i < ${#files[@]}; i++)); do diff "${files[i]}" "${files[i+1]}"; done

将连续的两个字节以一个字节单位倒序处理,并计算对应的10进制结果

1
  input=$(xxd -l 4 output_0001.bmp | awk '{print $3}' | sed -e 's/../&\ /g' | awk '{print $2$1}' | tr '[a-z]' '[A-Z]'); echo "obase=10; ibase=16; ${input}" | bc

命令拆解

这个命令的作用是从 output_0001.bmp 文件中提取前 4 字节的数据,将其转换为十进制数。让我们逐步拆解它:

  1. 提取数据:
1
   xxd -l 4 output_0001.bmp

xxd 工具将 output_0001.bmp 文件的前 4 字节以十六进制格式输出。每行输出包括地址、十六进制数据和 ASCII 表示。

  1. 提取十六进制数据:
1
   awk '{print $3}'

awk 从 xxd 的输出中提取第三列,这一列包含了十六进制数据。

  1. 格式化数据:
1
   sed -e 's/../&\ /g'

sed 用于在每两个字符之间插入一个空格,使其变成以空格分隔的十六进制对。

  1. 重排数据:
1
   awk '{print $2$1}'

awk 将第一列和第二列的十六进制对连接起来,通常这一步用来调整字节顺序。

  1. 转换为大写:
1
   tr '[a-z]' '[A-Z]'

tr 将十六进制数中的小写字母转换为大写字母。

  1. 计算十进制值:
1
   echo "obase=10; ibase=16; ${input}" | bc

bc 用于将处理后的十六进制字符串转换为十进制值。obase=10 设置输出为十进制,ibase=16 设置输入为十六进制。

总结: 这个命令将 BMP 文件的前 4 字节提取、格式化并转化为十进制数。

删除文件指定字节二进制数据

1
  output=$(input=$(xxd -l 4 output_0001.bmp | awk '{print $3}' | sed -e 's/../&\ /g' | awk '{print $2$1}' | tr '[a-z]' '[A-Z]'); echo "obase=10; ibase=16; ${input}" | bc); dd if=output_0001.bmp of=newBmp.bmp skip="${output}" bs=1024

将二进制文件16进制输出的情况下每两个字符后添加一个0并输出到另一个文件

1
  xxd -p output_0001.bmp | sed 's/../&0/g' > output.bmp

查找指定类型文件中的内容返回结果,并且会自动去除第一列的空格

由于结果并不是在第一列显示,因此让第一列为空,再把空格去掉

1
  echo "使用示例:$(find ./ -name "*.cpp" | xargs grep --color=always "$1" "$2" | awk '{$1=""; print $0}' | sed -e 's/^[ ]*//g' | sed -e 's/[ ]*$//g')"

显示文件最后修改时间

方式一

1
  stat ts1.c

方式二

1
  date -Ins -r ts1.c | tr ',' '.'

visual studio的dll相关文件拷贝到Qt工程的driver目录技巧

1
  mapfile -t files < <(find ./ -name "*DLL.h" -o -name "*.x64.dll" -o -name "*.x64.lib"); for i in "${files[@]}"; do cp -vf "${i}" ../03_Demo/PCIE_SGDMA-4CH_HTFD/driver/; done

命令行的shell脚本练习:read与case组合

1
  read key; case "${key}" in *) echo "${key}";;esac

执行结果:

1
2
3
$ read key; case "${key}" in *) echo "${key}";;esac
test
test

运行后输入test并回车,然后将输入结果打印出来。

shell脚本将case语句放在for循环中 - ChatGPT

在 Shell 脚本中,可以将 case 语句放入 for 循环中,以便对每个循环的项进行不同的处理。case 语句用于匹配某个条件,并根据条件执行相应的操作,结合 for 循环可以对多个元素做类似的处理。

以下是一个基本的例子,展示如何在 for 循环中使用 case 语句:

示例:使用 case 语句和 for 循环

假设你有一组文件名,你想根据文件扩展名进行不同的处理,可以在 for 循环中使用 case 语句来分类:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/bin/bash

# 假设有一组文件名
files=("file1.txt" "file2.jpg" "file3.png" "file4.txt" "file5.doc")

# 遍历文件名列表
for file in "${files[@]}"; do
  # 提取文件的扩展名
  extension="${file##*.}"

  # 使用 case 语句处理不同的扩展名
  case "$extension" in
    txt)
      echo "$file 是一个文本文件"
      ;;
    jpg|png)
      echo "$file 是一个图片文件"
      ;;
    doc)
      echo "$file 是一个文档文件"
      ;;
    *)
      echo "$file 是其他类型的文件"
      ;;
  esac
done

说明:

  • files=("file1.txt" "file2.jpg" "file3.png" "file4.txt" "file5.doc"):这是一个包含文件名的数组。
  • for file in "${files[@]}":遍历数组中的每个文件名。
  • extension="${file##*.}":通过 Shell 参数扩展提取文件的扩展名(即最后一个点 . 后面的部分)。
  • case "$extension" in … esac:根据文件扩展名做不同的处理。| 用于在 case 语句中匹配多个选项(例如 jpg|png)。

运行结果:

1
2
3
4
5
file1.txt 是一个文本文件
file2.jpg 是一个图片文件
file3.png 是一个图片文件
file4.txt 是一个文本文件
file5.doc 是一个文档文件

关键点:

  1. for 循环遍历一个列表或数组,并且对每个元素执行循环体中的操作。
  2. case 语句用于根据不同条件执行不同的代码块。在这个例子中,判断的是文件的扩展名。
    • 是 case 语句中的默认匹配模式,表示所有未匹配的情况。

这个示例展示了如何结合 for 循环和 case 语句来处理一系列数据,并根据不同的条件执行相应的操作。在 Shell 脚本中,这种结构非常常见且有效,尤其适用于分类处理和不同条件下的动作。

case语句+shift偏移参数

脚本代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
case $1 in
    param1)
	shift  # 移除第一个参数,$1 变成了原来的 $2
        for i in "$@"; do  # 循环处理剩余参数
            case $i in
                2)
                    echo "2"
                    ;;	
                3)
                    echo "3"
                    ;;
                *)  # 默认处理未匹配的情况
                    echo "Unrecognized input: $i"
                    ;;
            esac
        done    
        ;;
    param2)
	shift  # 移除第一个参数,$1 变成了原来的 $2
        for i in "$@"; do  # 循环处理剩余参数
            case $i in
                2)
                    echo "3"
                    ;;	
                3)
                    echo "4"
                    ;;
                *)  # 默认处理未匹配的情况
                    echo "Unrecognized input: $i"
                    ;;
            esac
        done    
        ;;
    *)  # 处理未匹配的主参数
        echo "Invalid command: $1"
        ;;
esac

运行示例

1
2
3
$ ./ts2.sh param1 2 3
2
3
1
2
3
$ ./ts2.sh param2 2 3
3
4

sed命令在包含指定关键词的行首与包含指定关键词的下一行的行首添加'//'

示例命令

1
  sed '/KEYWORD/{s/^/\/\//;n;s/^/\/\//}' input.txt

解释:

  • /KEYWORD/:查找包含 KEYWORD 的行。
  • {…}:表示一个代码块,包含多个操作。
  • s/^/\/\//:在匹配的行行首添加 //。这里的 ^ 是行首的符号。
  • n:n 命令让 sed 跳到下一行进行处理(并打印出该行)。
  • 再次执行 s/^/\/\//:在下一行的行首也添加 //。

解决使用脚本创建Makefile内容不对齐问题

使用echo命令,要加入-e选项开启转义,然后在需要加入制表符的地方插入\t,示例如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
{
echo -e 'DRIVER_NAME = xilinx-axidma'
echo -e '$(DRIVER_NAME)-objs = axi_dma.o axidma_chrdev.o axidma_dma.o axidma_of.o'
echo -e 'obj-m := $(DRIVER_NAME).o'
echo -e ''
echo -e 'SRC := $(shell pwd)'
echo -e ''
echo -e 'all:'
echo -e '\t$(MAKE) -C $(KERNEL_SRC) M=$(SRC)'
echo -e ''
echo -e 'modules_install:'
echo -e '\t$(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install'
echo -e ''
echo -e 'clean:'
echo -e '\trm -f *.o *~ core .depend .*.cmd *.ko *.mod.c'
echo -e '\trm -f Module.markers Module.symvers modules.order'
echo -e '\trm -rf .tmp_versions Modules.symvers'
} > ./project-spec/meta-user/recipes-modules/xilinx-axidma/files/Makefile

scp使用技巧

1
2
3
4
# 删除指定IP连接记录并上传本地公钥到远端 
sed -i '/192.168.1.10/d' ~/.ssh/known_hosts; ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.1.10
# 上传应用程序
scp test_axi_dma_v1/Debug/test_axi_dma_v1.elf root@192.168.1.10:/run/media/mmcblk0p1

使用Petalinux实现ZYNQ的linux程序开发(实现简单的socket通信程序)

Licensed under CC BY-NC-SA 4.0