如何在不知道文件名但知道其扩展名的情况下使用 shell 脚本读取文件
How to read a file without knowing its name but knowing its extension using shell script
我正在尝试更改我的代码以从目录中读取 .txt 文件。该目录只包含一个 .txt 文件,但我事先不知道它的名字。我只知道它是一个 .txt 文件。是否可以使用 shell 脚本来做到这一点?
下面是我当前读取文件的代码,但我必须手动指定文件名。
#!/bin/bash
declare -a var
filename='file.txt'
let count=0
while read line; do
var[$count]=$line
((count++))
done < $filename
你可以用这个。 head
命令用于此上下文以确保一个结果。
filename=$(ls *.txt | head -n 1)
如果您 100% 确定只有一个匹配文件,只需替换:
done < $filename
作者:
done < *.txt
当然,如果您有零个或多个匹配文件,这将失败。因此,最好先进行测试。例如:
tmp=$(shopt -p nullglob || true)
shopt -s nullglob
declare -a filename=(*.txt)
if (( ${#filename[@]} != 1 )); then
printf 'error: zero or more than one *.txt file\n'
else
declare -a var
let count=0
while read line; do
var[$count]=$line
((count++))
done < "${filename[0]}"
fi
eval "$tmp"
shopt
东东将nullglob
选项的当前状态存储在变量tmp
中,启用选项,最后恢复初始状态。如果存在 *.txt
文件为零的风险,则需要在此处启用 nullglob
。没有 nullglob
会将文字字符串 *.txt
存储在数组 filename
.
中
您的循环可以稍微优化一下:
declare -a var
while IFS= read -r line; do
var+=("$line")
done < "${filename[0]}"
需要 IFS=
来保留读取行中的前导和尾随空格。如果这不是您想要的,请将其删除。 read
的 -r
选项在读取行中保留反斜杠。如果这不是您想要的,请将其删除。 +=
赋值自动在索引数组的末尾添加一个元素。不用数了。如果您想知道您的数组包含多少元素,只需使用 ${#var[@]}
就像我们测试 filename
数组的长度一样。
请注意,如果您的 bash 版本足够新,则最好使用 mapfile
将文本文件的内容存储在 bash 数组中。例如,参见 。
也可以在赋值中触发参数扩展!
filename=$(echo -n *.txt)
如果你想万无一失(捕获匹配文件数不为1的情况),分配给一个数组并检查它的大小:
farr=( *.txt )
if (( ${#farr[*]} != 1 ))
then
echo You lied to may when you said that there is exactly on .txt file
else
filename=${farr[0]}
fi
我正在尝试更改我的代码以从目录中读取 .txt 文件。该目录只包含一个 .txt 文件,但我事先不知道它的名字。我只知道它是一个 .txt 文件。是否可以使用 shell 脚本来做到这一点?
下面是我当前读取文件的代码,但我必须手动指定文件名。
#!/bin/bash
declare -a var
filename='file.txt'
let count=0
while read line; do
var[$count]=$line
((count++))
done < $filename
你可以用这个。 head
命令用于此上下文以确保一个结果。
filename=$(ls *.txt | head -n 1)
如果您 100% 确定只有一个匹配文件,只需替换:
done < $filename
作者:
done < *.txt
当然,如果您有零个或多个匹配文件,这将失败。因此,最好先进行测试。例如:
tmp=$(shopt -p nullglob || true)
shopt -s nullglob
declare -a filename=(*.txt)
if (( ${#filename[@]} != 1 )); then
printf 'error: zero or more than one *.txt file\n'
else
declare -a var
let count=0
while read line; do
var[$count]=$line
((count++))
done < "${filename[0]}"
fi
eval "$tmp"
shopt
东东将nullglob
选项的当前状态存储在变量tmp
中,启用选项,最后恢复初始状态。如果存在 *.txt
文件为零的风险,则需要在此处启用 nullglob
。没有 nullglob
会将文字字符串 *.txt
存储在数组 filename
.
您的循环可以稍微优化一下:
declare -a var
while IFS= read -r line; do
var+=("$line")
done < "${filename[0]}"
需要 IFS=
来保留读取行中的前导和尾随空格。如果这不是您想要的,请将其删除。 read
的 -r
选项在读取行中保留反斜杠。如果这不是您想要的,请将其删除。 +=
赋值自动在索引数组的末尾添加一个元素。不用数了。如果您想知道您的数组包含多少元素,只需使用 ${#var[@]}
就像我们测试 filename
数组的长度一样。
请注意,如果您的 bash 版本足够新,则最好使用 mapfile
将文本文件的内容存储在 bash 数组中。例如,参见
也可以在赋值中触发参数扩展!
filename=$(echo -n *.txt)
如果你想万无一失(捕获匹配文件数不为1的情况),分配给一个数组并检查它的大小:
farr=( *.txt )
if (( ${#farr[*]} != 1 ))
then
echo You lied to may when you said that there is exactly on .txt file
else
filename=${farr[0]}
fi