我试图通过脚本传递带有某些名称的 flatdb,以便忽略某些字段并检查其他字段。目前这是我所得到的。
我将在 then 语句中使用什么来忽略注释和空格行?
编辑:正在读取的文件示例
Bob,Brown,Smith,39
#Alex,Jay,Jones,83
Justin,Michael,White,18
James,Paul,Weis,54
编辑:然后我将每个名字分开
IFS_SAVE=${IFS}
IFS=,
while read value1 value2 value3 value4
do
echo "First name ${value1}"
echo "Middle name ${value2}"
echo "Last name ${value3}"
echo "Age ${value4}"
done < ${1}
然后我试图忽略文件中的空白行
while read value1 value2 value3 value4
do
if [ -z ${value1} ]
then
echo "blank line exists"
fi
done < ${1}
然后我尝试忽略文件中的注释行
while read value1 value2 value3 value4
do
if [ "${value1:0:1}" = "#" ]
then
echo "comment exists"
fi
done < ${1}
从这里开始我一直无法让它真正发挥作用
我正在尝试检查字段是否以空格开头或结尾
while read value1 value2 value3 value4
do
if [[ ${value1} = *[[:space:]]* ]]
then
echo "space exist"
fi
done < ${1}
编辑:理想输出
First name Bob
Middle name Brown
Last name Smith
Age 39
First name Justin
Middle name Michael
Last name White
Age 39
James,Paul,Wise,54 space exist
答案1
使用文本处理工具来处理文本,而不是循环调用数百次不适当的工具,例如read
或echo
。
在这里,处理表格数据的明显方法是awk
:
awk -F, -v OFS='\n' '
! /^[#[:space:]]/ {
print "First name " $1, \
"Middle name " $2, \
"Last name " $3, \
"Age " $4
}' < you-file
条件与! /^[#[:space:]]/
( ) 不以or!
开头 ( ^
)的行相匹配#
空白特点。您还可以匹配以或/^[^#[:space:]]/
以外的字符开头的行#
空白实际上,这也会跳过空行或添加&& NF == 4
以跳过不包含 4 个字段的行。
或者按照预期输出中的方式原样传递带有前导或尾随空格的行:
awk -F, -v OFS='\n' '
/^[[:space:]]/ || /[[:space:]]$/ {print; next}
/^[^#]/ && NF == 4 {
print "First name " $1, \
"Middle name " $2, \
"Last name " $3, \
"Age " $4
}' < you-file
(在这里,我们假设 POSIX 兼容awk
; 将mawk
, 替换[:space:]
为您希望在开始时找到的空白字符的硬编码列表,因为mawk
不支持 POSIX 字符类)。
另请注意,回车符(又名 CR // \r
)^M
被视为一个[:space:]
字符。如果输入文件是来自 Microsoft 操作系统的文本文件,其中行分隔符是 CRLF 而不是 Unix 中的 LF,则每行将以空白特点。您需要dos2unix
首先运行该文件以将其转换为 Unix 格式。
答案2
由于分词发生在 IFS 上,并且默认 IFS 由 'tab/space/newline' 组成,并且您需要将 IFS 设置为逗号,
,因此您需要:
while IFS=, read -r …
并且也更改${value1} = *[[:space:]]*
为"${value1}" =~ ^[[:space:]]
模式匹配那以空格开头;并且没有真正的单词意味着这就是 IFS 的分割方式(这里是一个逗号)。