在 bash 中将行分配给带有分隔符的变量
Assign lines to variables with separator in bash
我有一个从 grep 输出构建的文件,它看起来像这样:
http://google.fr
Pierre google
http://test.fr
--
http://yahoo.com
Jean Yahoo
http://test.fr
--
我为每 3 行创建了一个分隔符“--”。我想将每一行分配给一个变量,例如:
url= "http://google.fr"
name= "Pierre Google"
web= "http://test.fr"
所以我用 IFS=-- 制作了 bash 脚本,我尝试使用 echo 的 -d 选项,但我不知道如何将这 3 行分配给每个块的变量.
感谢您的帮助
通过一些错误处理,这可能看起来像:
while read -r url && read -r name && read -r web; do
echo "Read url of $url, name of $name, and web of $web"
read -r sep || { true; break; } # nothing to read: exit loop w/ successful $?
if [[ $sep != -- ]]; then
printf 'Expected separator, but saw: %q\n' "$sep" >&2
false; break # "--" not seen where expected; exit loop w/ $? indicating failure
fi
done <in.txt
(顺便说一句——如果你不想去除前导和尾随的空格,我建议用 IFS=
清除 IFS——要么限定在 read
s 中,如 while IFS= read -r url && IFS= read -r name && IFS= read -r web
,或者如果没有其他事情发生在不希望有副作用的地方,则对脚本是全局的。
这应该适合你的情况
NR=0
while read LINE; do
((NR++))
case $NR in
1)
URL=$LINE
;;
2)
NAME=$LINE
;;
3)
WEB=$LINE
;;
4)
if [ $LINE = "--" ]; then
NR=0
#
# DO WHAT EVER YOU WANT TO DO WITH YOUR DATA HERE
#
#
echo "$URL;;$NAME;;$WEB"
else
echo "wrong delimiter found \"$LINE\""
fi
;;
esac
done
运行 它与
script.sh < inputfile.txt
或者只是将 grep 命令的输出通过管道传递给脚本。
您可以将文件预处理为更典型的格式,以使用 IFS 通过 awk
或 sed
:
等实用程序分隔字段(或变量)
while IFS="|" read -r url name web; do
echo "$url" "$name" "$web"
done < <(awk 'BEGIN{RS="--\n"; FS="\n"; OFS="|"} {print ,,}' file)
这会保留每行的前导和尾随空格。
如果要去除前导和尾随空格,请删除 IFS="|"
和 OFS="|"
部分,以便 Bash 去除以下行:
while read -r url name web; do
echo "$url" "$name" "$web"
done < <(awk 'BEGIN{RS="--\n"; FS="\n"} {print ,,}' file)
我有一个从 grep 输出构建的文件,它看起来像这样:
http://google.fr
Pierre google
http://test.fr
--
http://yahoo.com
Jean Yahoo
http://test.fr
--
我为每 3 行创建了一个分隔符“--”。我想将每一行分配给一个变量,例如:
url= "http://google.fr"
name= "Pierre Google"
web= "http://test.fr"
所以我用 IFS=-- 制作了 bash 脚本,我尝试使用 echo 的 -d 选项,但我不知道如何将这 3 行分配给每个块的变量.
感谢您的帮助
通过一些错误处理,这可能看起来像:
while read -r url && read -r name && read -r web; do
echo "Read url of $url, name of $name, and web of $web"
read -r sep || { true; break; } # nothing to read: exit loop w/ successful $?
if [[ $sep != -- ]]; then
printf 'Expected separator, but saw: %q\n' "$sep" >&2
false; break # "--" not seen where expected; exit loop w/ $? indicating failure
fi
done <in.txt
(顺便说一句——如果你不想去除前导和尾随的空格,我建议用 IFS=
清除 IFS——要么限定在 read
s 中,如 while IFS= read -r url && IFS= read -r name && IFS= read -r web
,或者如果没有其他事情发生在不希望有副作用的地方,则对脚本是全局的。
这应该适合你的情况
NR=0
while read LINE; do
((NR++))
case $NR in
1)
URL=$LINE
;;
2)
NAME=$LINE
;;
3)
WEB=$LINE
;;
4)
if [ $LINE = "--" ]; then
NR=0
#
# DO WHAT EVER YOU WANT TO DO WITH YOUR DATA HERE
#
#
echo "$URL;;$NAME;;$WEB"
else
echo "wrong delimiter found \"$LINE\""
fi
;;
esac
done
运行 它与
script.sh < inputfile.txt
或者只是将 grep 命令的输出通过管道传递给脚本。
您可以将文件预处理为更典型的格式,以使用 IFS 通过 awk
或 sed
:
while IFS="|" read -r url name web; do
echo "$url" "$name" "$web"
done < <(awk 'BEGIN{RS="--\n"; FS="\n"; OFS="|"} {print ,,}' file)
这会保留每行的前导和尾随空格。
如果要去除前导和尾随空格,请删除 IFS="|"
和 OFS="|"
部分,以便 Bash 去除以下行:
while read -r url name web; do
echo "$url" "$name" "$web"
done < <(awk 'BEGIN{RS="--\n"; FS="\n"} {print ,,}' file)