Linux 如何使用IFS读入bash脚本中的一行,并在读取该行时在指定字符之间创建新行

Linux 如何使用IFS读入bash脚本中的一行,并在读取该行时在指定字符之间创建新行,linux,bash,Linux,Bash,我正在尝试创建一个bash脚本,该脚本将在一个只有一行的文件中读取,当它正在读取该行并遇到空白时,创建一个新行,然后继续读取该行 试图读取的文件 david:69 jim:98 peter:21 sam:56 april:32 这是我当前的bash脚本 #!/bin/bash fileName=$1 # storing the file numberSpaces=$2 # will be used later to specify the number of spaces inbetween

我正在尝试创建一个bash脚本,该脚本将在一个只有一行的文件中读取,当它正在读取该行并遇到空白时,创建一个新行,然后继续读取该行

试图读取的文件

david:69 jim:98 peter:21 sam:56 april:32
这是我当前的bash脚本

#!/bin/bash

fileName=$1 # storing the file
numberSpaces=$2 # will be used later to specify the number of spaces inbetween name:score

# Checking if no file was specified on the command line
[ $# -eq 0 ] && { echo "No file specified"; exit 1;}

# Checking if the file entered on the command line exists
[ ! -f $fileName ] && { echo "File $fileName not found."; exit 2;}

# Internal Field Seperator(IFS) will read what is on the left and right of a specified char
while IFS='  ' read -r name;
do
  echo "$name"
  echo -e "\n"
done < $fileName

#while read -r line
#do
#   name="$line"
#   echo "Content of file - $name"
#done < "$fileName"
它目前只在一行上打印文件内容。 如果您有任何帮助或建议,我们将不胜感激

tr -s " " "\n" < file.txt
tr-s”“\n”
在一行中:

tr -s " " "\n" < file.txt
tr-s”“\n”
您需要使用
读取
中的
-d
选项使其读取到给定的分隔符:

while IFS= read -r -d ' ' name;
do
  echo "$name"
done < <(sed 's/$/ /' file.txt)

sed
用于在行尾插入一个空格,以便
-d
可以使用空格作为分隔符,

您需要使用
读取
中的
-d
选项将其读取到给定的分隔符:

while IFS= read -r -d ' ' name;
do
  echo "$name"
done < <(sed 's/$/ /' file.txt)

sed
用于在行尾插入空格,以便
-d
可以使用空格作为分隔符,

您可以将行拆分为一个数组,然后在该数组上迭代

read -r -a fields < "$fileName"
for field in "${fields[@]}"; do
  echo "$field"
done

您可以将该行拆分为一个数组,然后在该数组上迭代

read -r -a fields < "$fileName"
for field in "${fields[@]}"; do
  echo "$field"
done


另一方面,
echo-e
是一种糟糕的形式——而bash支持它的开箱即用(除非
posix
xpg_echo
选项都被启用),使得它的实现在输出上执行任何使打印
-e
非法的操作(不仅仅是未指定的扩展,而是主动的违规)。改为使用
printf
——对于常量字符串可以使用
printf'\n'
,对于动态字符串可以使用
printf'%b'$string'\u和\u escape\u序列“
。谢谢@Charles Duffy指出我的错误形式。我将确保今后不再这样做。生活和学习。顺便说一句,
echo-e
是一种糟糕的形式——而bash支持它开箱即用(除非同时启用了
posix
xpg_echo
选项),使得它的实现在输出时执行任何使打印
-e
非法的操作(不仅仅是一个未指定的扩展,而是一个主动违反)。改为使用
printf
——对于常量字符串可以使用
printf'\n'
,对于动态字符串可以使用
printf'%b'$string'\u和\u escape\u序列“
。谢谢@Charles Duffy指出我的错误形式。我将确保今后不再这样做。生活和学习。我会考虑使用<代码> Prtff '%s\n ' $field(<$field)< /> >——如果我们逐字逐句地进行,可能会有“代码> -N/CODE”作为一个词。谢谢@查普纳,你的建议是通过输入来把它放进一个数组中,并且很容易修改,以便自定义输出到屏幕。我会考虑使用<代码> Prtff '%s\n ' $field(< $field)< /代码>——如果我们逐字逐句地说,可能有
-n
作为一个词。感谢@chepner提供您的回复。您建议的方法是将输入内容放入数组中,效果非常好,并且很容易修改,以便自定义屏幕输出。使用IFS匹配制表符、空格和换行符:
tr-s“$IFS”“\n”
tr
仅适用于单个字符。对于多个字符,请使用sed:
sed's//\n\n/g'
Thank you@Ipor Sircer,感谢您的回复,非常好,只需一行代码即可轻松理解。我将如何使用您的方法创建和加倍新线?谢谢@Ipor Sircer您的帮助。我将回顾sed上的手册页。sed几乎是一种编程语言。下面是一些基础知识:使用IFS匹配制表符、空格和换行符:
tr-s“$IFS”“\n”
tr
仅适用于单个字符。对于多个字符,请使用sed:
sed's//\n\n/g'
Thank you@Ipor Sircer,感谢您的回复,非常好,只需一行代码即可轻松理解。我将如何使用您的方法创建和加倍新线?谢谢@Ipor Sircer您的帮助。我将回顾sed上的手册页。sed几乎是一种编程语言。以下是一些基本信息:感谢@anubhava的回复,但您发布的内容似乎没有打印最后一个人及其分数。感谢@anubhava的回复,但您发布的内容似乎没有打印最后一个人及其分数。