shell获取文件总行数的6中方法

本文介绍使用awk、grep、sed、wc及cat等命令统计Shell脚本文件行数的方法,包括直接显示最后一行行号、利用正则表达式过滤并显示行号、通过sed命令仅输出最后一行行号、使用wc命令计数以及通过管道操作结合cat和wc实现行数统计。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. awk '{print NR}' test1.sh|tail -n1
  2. awk 'END{print NR}' test1.sh
  3. grep -n "" test1.sh|awk -F: '{print '}|tail -n1
  4. sed -n '$=' test1.sh
  5. wc -l test1.sh
  6. cat test1.sh |wc -l

欢迎关注,更多惊喜等着你

这里写图片描述

<think>我们有一个明确的任务:在Shell脚本中将文件内容读取到数组变量中。根据提供的引用,特别是引用[5]展示了如何将命令的输出(这里是egrep的结果)赋值给数组。我们可以借鉴这个方法。另外,引用[2]和引用[4]也涉及到数组的使用,我们可以参考。在Shell中,读取文件内容到数组的常见方法有几种:1.使用`mapfile`或`readarray`命令(在Bash4.0及以上版本可用),这是最直接的方法。2.使用循环逐行读取并添加到数组。3.将命令输出的每一行作为数组元素,可以通过命令替换和数组赋值实现。由于引用[5]中使用了命令替换来初始化数组,我们可以采用类似的方式。但是,注意引用[5]中的例子是读取命令输出的多行,每一行成为一个数组元素。同样,我们可以使用`cat`命令来读取文件,但是要注意,如果文件很大,这种方法可能不是最高效的。另外,引用[3]中有一个读取用户输入的例子,我们可以借鉴其读取文件的方式。下面我将提供两种常见的方法方法一:使用`mapfile`(或`readarray`,两者等价)语法:`mapfile-tarray_name<filename`说明:`-t`选项会移除每一行末尾的换行符。方法二:使用循环读取我们可以使用`while`循环逐行读取文件并添加到数组。方法三:使用命令替换(如果文件内容不包含空格等特殊字符,且每行作为数组元素)例如:`array=($(catfilename))`但是这种方法有一个问题:命令替换会进行单词分割(根据IFS变量),所以如果一行中有空格,它会被分割成多个元素。因此,通常我们不推荐这种方法来按行存储,除非我们确实希望按单词分割。所以,为了按行存储,我们应该避免使用命令替换的分词。我们可以设置IFS(内部字段分隔符)为换行符,然后使用命令替换,但是仍然要注意命令替换会去除尾随换行符,并且如果文件最后一行没有换行符,可能会出现问题。更安全的方法是使用`mapfile`或者循环。由于引用[5]中使用了命令替换,并且他们匹配的是多行,但是他们的例子中每一行都作为一个元素吗?实际上,命令替换中,如果命令输出多行,那么每个换行符分隔的行都会成为数组的一个元素。但是,需要注意的是,命令替换会进行分词和路径扩展。为了避免分词,我们可以设置IFS仅包含换行符,并禁用路径扩展。因此,我们可以这样:set-f#禁用路径扩展IFS=$'\n'#设置字段分隔符为换行符array=($(catfilename))set+f#恢复路径扩展但是这种方法仍然不能处理包含通配符的行(因为路径扩展)以及包含空格的行(如果IFS设置正确,则不会按空格分割,但路径扩展可能会将*等扩展为文件列表)。所以,更推荐使用`mapfile`或者循环。考虑到兼容性(如果bash版本较低,没有`mapfile`),我们可以使用循环。下面我们分别展示:方法一(推荐,如果Bash版本>=4):```bashmapfile-tmy_array<filename```或者```bashreadarray-tmy_array<filename```方法二(兼容性好):```bashmy_array=()whileIFS=read-rline;domy_array+=("$line")done<filename```注意:`IFS=`是为了防止行首尾的空白被移除,`-r`是为了防止反斜杠转义。根据引用[4]中的数组赋值方式,我们可以使用类似`my_array+=("$line")`来追加元素。现在,我们来写一个完整的脚本例子,包含错误处理(比如文件不存在)。参考引用[3]中的错误处理,我们可以先检查文件是否存在并可读。脚本示例:```bash#!/bin/bash#检查参数if[$#-ne1];thenecho"用法:$0文件名"exit1fifilename="$1"#检查文件是否存在并可读if[!-r"$filename"];thenecho"错误:文件'$filename'不存在或不可读。"exit1fi#方法1:使用mapfile(Bash4及以上)#检查是否存在mapfile命令ifdeclare-Fmapfile&>/dev/null;thenmapfile-tmy_array<"$filename"else#方法2:使用循环my_array=()whileIFS=read-rline;domy_array+=("$line")done<"$filename"fi#显示数组内容(为了演示,我们显示前5行)echo"数组内容(前5行):"foriin"${!my_array[@]}";doif[$i-lt5];thenecho"行$((i+1)):${my_array[$i]}"elsebreakfidone#或者直接显示数组所有元素(如果文件很大,不建议全部显示)#echo"所有数组元素:"#printf"%s\n""${my_array[@]}"```注意:上面的脚本中,我们检查了`mapfile`命令是否存在,如果不存在则使用循环方法。另外,我们通过参数传递文件名,并检查了参数个数和文件可读性。现在,我们根据要求生成相关问题:§§相关问题§§1.在Shell脚本中,如何检查一个文件是否存在并可读?2.除了使用`mapfile`和循环,还有其他方法文件内容读取到数组吗?3.如何避免在读取文件到数组时遇到特殊字符(如空格、星号等)的问题?4.如果文件非常大,使用哪种方法读取到数组会更高效?5.在Shell脚本中,如何获取数组的长度和遍历数组?</think>在 Shell 脚本中将文件内容读取到数组变量中,主要有以下三种方法: ### 方法 1:使用 `mapfile` 命令(推荐) ```bash #!/bin/bash filename="your_file.txt" # 检查文件是否存在 if [ ! -f "$filename" ]; then echo "错误:文件不存在" >&2 exit 1 fi # 读取文件内容到数组 mapfile -t file_array < "$filename" # 验证结果 echo "数组长度: ${#file_array[@]}" echo "第一行内容: ${file_array[0]}" echo "最后一行内容: ${file_array[-1]}" ``` **说明**: - `-t` 选项自动移除行尾换行符 - 每行文本作为独立数组元素存储 - 需要 Bash 4.0+ 版本支持 ### 方法 2:使用 `read` 循环 ```bash #!/bin/bash filename="your_file.txt" file_array=() # 读取文件到数组 while IFS= read -r line; do file_array+=("$line") done < "$filename" # 验证结果 echo "行数: ${#file_array[@]}" for i in "${!file_array[@]}"; do echo "行 $((i+1)): ${file_array[$i]}" done ``` **说明**: - `IFS=` 防止首尾空格被截断 - `-r` 禁止反斜杠转义 - 兼容所有 Bash 版本 ### 方法 3:命令替换(简单文件) ```bash #!/bin/bash filename="your_file.txt" # 设置IFS仅用换行符分隔 IFS=$'\n' # 读取文件到数组 file_array=($(cat "$filename")) # 还原IFS unset IFS # 显示结果 echo "数组内容: ${file_array[*]}" ``` **注意**:此方法可能因特殊字符(空格、星号等)导致元素分割错误[^2],仅推荐处理简单文本。 ### 关键要点 1. **元素对应关系**:每行文本成为数组的一个独立元素 2. **特殊字符处理**:推荐使用 `mapfile` 或 `read -r` 避免转义问题 3. **空行处理**:空行会创建空字符串元素(索引仍占用) 4. **大文件优化**:使用 `while read` 循环内存效率最高 5. **引用元素**:必须用双引号 `${array[@]}` 防止元素分割 > 示例文件内容: > ``` > 第一行文本 > 第二行:包含空格 > 第三行*特殊字符* > ``` > 执行结果: > ``` > 数组长度: 3 > 第一行内容: 第一行文本 > 最后一行内容: 第三行*特殊字符* > ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值