用BASH实现多文件同时添加或删除的编辑操作
1. 添加文本方法一:当前目录下的文件(不递归子目录)
1: for file in *.org; do 2: { printf "要添加的代码(末尾自动换行)\n"; cat "$file"; } > "$file.tmp" \ 3: && mv "$file.tmp" "$file" 4: done
1.1. 代码逐行解释
1.1.1. for file in *.org; do
for … in …; do:这是 bash 中的 for 循环结构,用于遍历一组元素。 file:是循环变量,在每次循环中,它会依次被赋值为 .org 所匹配到的文件名。 *.org:是一个通配符表达式, 表示匹配任意数量(包括零个)的任意字符,所以 *.org 表示匹配当前目录下所有扩展名为 .org 的文件。 do:表示循环体的开始。
1.1.2. { printf "要添加的代码(末尾自动换行)\n"; cat "$file"; } > "$file.tmp"
{ … }:这是 bash 中的命令组语法,用于将多个命令组合在一起,当作一个整体来处理。 printf "要添加的代码(末尾自动换行)\n":printf 是一个格式化输出命令,这里会输出字符串 “要添加的代码(末尾自动换行)”,并在末尾添加一个换行符 \n。 cat "$file":cat 命令用于读取文件内容并输出到标准输出,"$file" 是循环变量,代表当前正在处理的 .org 文件。这里会将该文件的内容输出。 > "$file.tmp":这是输出重定向符号,将前面命令组的输出结果(即要添加的代码行和原文件内容)重定向到一个临时文件,文件名是当前处理文件的文件名加上 .tmp 后缀。
1.1.3. && mv "$file.tmp" "$file"
&&:这是逻辑与运算符,只有当它前面的命令执行成功(返回状态码为 0)时,才会执行后面的命令。 mv "$file.tmp" "$file":mv 是移动(重命名)文件的命令,这里将临时文件 $file.tmp 重命名为原文件 $file,从而实现用修改后的内容覆盖原文件。
1.1.4. done
表示 for 循环体的结束。
1.2. 总结
整个程序通过 for 循环遍历当前目录下所有 .org 文件,对于每个文件,先将指定的代码行和原文件内容输出到一个临时文件,然后将临时文件重命名为原文件,最终实现了在每个 .org 文件开头添加指定代码行的功能。
2. 添加文本方法二:当前目录下的文件(递归子目录)
1: find . -name "*.org" -exec sh -c ' 2: file="$1"; 3: { printf "要添加的代码\n"; cat "$file"; } > "$file.tmp" \ 4: && mv "$file.tmp" "$file" 5: ' _ {} \;
2.1. 整体功能概述
这段代码的主要功能是在当前目录(.)及其所有子目录中查找所有扩展名为 .org 的文件,然后在每个找到的 .org 文件开头添加一行指定的代码(“要添加的代码”),并覆盖原文件内容。下面我们来详细解释代码的每一部分。 代码逐行解释
2.1.1. find . -name "*.org"
find:这是一个用于在文件系统中查找文件和目录的强大命令。 .:指定查找的起始目录,这里表示当前目录。 -name ".org":这是查找的条件,-name 选项用于按照文件名进行匹配,.org 是一个通配符表达式,* 表示匹配任意数量(包括零个)的任意字符,所以该表达式表示匹配所有扩展名为 .org 的文件。
2.1.2. -exec sh -c '
-exec:find 命令的一个选项,用于对找到的每个文件执行指定的命令。 sh -c: sh 是一个常用的 shell 解释器,用于执行 shell 脚本。 -c 是 sh 的选项,用于从字符串中读取并执行命令。sh -c '…' 表示将单引号内的字符串作为一个 shell 命令来执行。
2.1.3. file="$1";
在 sh -c 执行的命令中,$1 是一个位置参数,它会被替换为 find 命令找到的当前文件的名称。这行代码将当前文件的名称赋值给变量 file,方便后续使用。
2.1.4. { printf "要添加的代码\n"; cat "$file"; } > "$file.tmp"
{ … }:这是 bash 中的命令组语法,用于将多个命令组合在一起当作一个整体处理。 printf "要添加的代码\n":printf 是格式化输出命令,它会输出字符串 “要添加的代码”,并在末尾添加一个换行符 \n。 cat "$file":cat 命令用于读取文件内容并输出到标准输出,"$file" 是前面赋值的当前处理文件的名称,这里会将该文件的内容输出。 > "$file.tmp":这是输出重定向符号,将前面命令组的输出结果(即要添加的代码行和原文件内容)重定向到一个临时文件,文件名是当前处理文件的名称加上 .tmp 后缀。
2.1.5. && mv "$file.tmp" "$file"
&&:逻辑与运算符,只有当它前面的命令执行成功(返回状态码为 0)时,才会执行后面的命令。 mv "$file.tmp" "$file":mv 是移动(重命名)文件的命令,这里将临时文件 $file.tmp 重命名为原文件 $file,从而实现用修改后的内容覆盖原文件。
2.1.6. ' _ {} \;
_:sh -c 会将第一个参数作为脚本名,这里用 _ 来占位。 {}:是 find 命令 -exec 选项的占位符,表示当前找到的文件。 \;:是 -exec 命令的结束标志。
2.2. 总结
整个程序结合了 find 命令的文件查找功能和 sh -c 的命令执行功能,先找出所有 .org 文件,然后对每个文件在开头添加指定代码行,通过临时文件的方式完成文件内容的修改并覆盖原文件。
3. 删除文本方法一:直接操作(推荐)
1: find . -maxdepth 2 -name "*.org" -exec sed -i \ 2: -e '/需要删除的文本/d' \ 3: -e '/需要伸出的文本2/d' {} \;
3.1. 整体功能概述
这段代码的主要功能是在当前目录(.)及其下最多两层子目录中查找所有扩展名为 .org 的文件,然后使用 sed 命令从这些文件里删除包含指定文本的行。 代码逐行详细解释
3.1.1. find . -maxdepth 2 -name "*.org"
find:这是一个用于在文件系统中查找文件和目录的强大命令。 .:表示查找操作的起始目录,这里指定为当前目录。 -maxdepth 2:-maxdepth 是 find 命令的一个选项,用于限制查找的目录深度。2 意味着查找操作只会在当前目录以及它的下两层子目录中进行,不会再深入到更深层次的子目录,这样可以避免不必要的递归查找,提高查找效率。 -name ".org":-name 选项用于根据文件名进行匹配。.org 是一个通配符表达式,其中 * 可以匹配任意数量(包括零个)的任意字符,所以该表达式表示匹配所有扩展名为 .org 的文件。
3.1.2. -exec
-exec 是 find 命令的一个重要选项,它的作用是对查找到的每个文件执行指定的命令。其基本语法是 -exec command {} \;,其中 {} 是一个占位符,代表当前找到的文件,\; 是命令结束的标志。
3.1.3. sed -i
sed:是一个流编辑器,常用于对文本进行替换、删除、插入等操作。它逐行处理输入的文本,并根据用户提供的脚本对文本进行修改。 -i:sed 命令的选项,-i 表示直接在原文件上进行修改。如果不使用 -i 选项,sed 命令会将修改后的结果输出到标准输出,而原文件不会被改变。
3.1.4. -e '/需要删除的文本/d'
-e:sed 命令的选项,用于指定要执行的脚本命令。可以使用多个 -e 选项来依次执行多个不同的脚本命令。 需要删除的文本/d:这是 sed 的一个具体脚本命令。 之间的内容是要匹配的模式,这里的模式是 需要删除的文本。d 是 sed 中的删除命令,整个命令的意思是:如果某一行包含 需要删除的文本,则将这一行从文本中删除。
3.1.5. -e '/需要删除的文本2/d'
同理,这也是一个 sed 脚本命令。它会查找包含 需要删除的文本2 的行,并将这些行从文本中删除。
3.1.6. {} 和 \;
{}:如前面所述,是 find 命令 -exec 选项的占位符,代表当前找到的 .org 文件。在执行 sed 命令时,{} 会被替换为具体的文件名。 \;:是 -exec 选项的结束标志,告诉 find 命令,前面的命令到此结束,可以开始处理下一个找到的文件了。
3.2. 总结
整个代码通过 find 命令筛选出符合条件的 .org 文件,然后使用 sed 命令对这些文件进行处理,删除其中包含指定文本的行,并且直接修改原文件。
4. 删除文本方法二:安全操作(备份原文件)
1: find . -maxdepth 2 -name "*.org" -exec sed -i.bak \ 2: -e '/需要删除的文本/d' \ 3: -e '/需要删除的文本2/d' {} \;
4.1. 整体功能概述
该代码会在当前目录(.)及其下最多两层子目录中查找所有扩展名为 .org 的文件,接着使用 sed 命令删除这些文件中包含指定文本的行,同时会为每个被修改的文件创建一个备份。 代码详细解释
4.1.1. find . -maxdepth 2 -name "*.org"
find:这是一个在文件系统中查找文件和目录的命令。 .:指定查找操作的起始目录为当前目录。 -maxdepth 2:-maxdepth 是 find 命令的一个选项,用于限制查找的目录深度。这里设置为 2,意味着查找操作只会在当前目录以及它下面两层的子目录中进行,不会再深入到更深层次的子目录,避免了不必要的递归查找,提高查找效率。 -name ".org":-name 选项用于根据文件名进行匹配。.org 是一个通配符表达式,其中 * 表示可以匹配任意数量(包括零个)的任意字符,所以该表达式表示匹配所有扩展名为 .org 的文件。
4.1.2. -exec
-exec 是 find 命令的一个关键选项,它的作用是对查找到的每个文件执行指定的命令。其语法结构为 -exec command {} \;,其中 {} 是一个占位符,代表当前找到的文件,\; 是命令结束的标志。
4.1.3. sed -i.bak
sed:是一个强大的流编辑器,用于对文本进行替换、删除、插入等操作。它逐行读取输入的文本,并根据用户提供的脚本对文本进行相应修改。 -i.bak:-i 表示直接在原文件上进行修改。.bak 是一个后缀,当使用 -i 并指定后缀时,sed 在修改原文件之前会先为原文件创建一个备份,备份文件的名称是原文件名加上 .bak 后缀。例如,如果原文件名为 example.org,备份文件名将是 example.org.bak。
4.1.4. -e '/需要删除的文本/d'
-e:sed 命令的选项,用于指定要执行的脚本命令。可以使用多个 -e 选项来依次执行多个不同的脚本命令。 需要删除的文本/d:这是 sed 的一个具体脚本命令。 之间的内容是要匹配的模式,这里的模式是 需要删除的文本。d 是 sed 中的删除命令,整个命令的含义是:如果某一行包含 需要删除的文本,则将这一行从文本中删除。
4.1.5. -e '/需要删除的文本2/d'
同理,这也是一个 sed 脚本命令。它会查找包含 需要删除的文本2 的行,并将这些行从文本中删除。 {} 和 \;
{}:作为 find 命令 -exec 选项的占位符,代表当前找到的 .org 文件。在执行 sed 命令时,{} 会被替换为具体的文件名。 \;:是 -exec 选项的结束标志,告知 find 命令前面的命令已经结束,可以开始处理下一个找到的文件了。
4.2. 总结
整个代码通过 find 命令定位到符合条件的 .org 文件,然后使用 sed 命令对这些文件进行修改,删除包含指定文本的行,并且会为每个修改的文件创建一个备份。