为什么我的“回声”只显示一个单词?(LinuxBash)

为什么我的“回声”只显示一个单词?(LinuxBash),linux,bash,Linux,Bash,我有一个username.txt,它显示用户名和组,用一个、,。我试图只将用户名从访问者组复制到新的txt my usernamet.txt: mark,staff jason,visitor jack,visitor orlando,visitor 这是我当前的bash脚本: #!/bin/bash username=username.txt while IFS=, read username1 group1; do if [ $group1 = "visitor"

我有一个username.txt,它显示用户名和组,用一个、,。我试图只将用户名从访问者组复制到新的txt

my usernamet.txt:

mark,staff
jason,visitor
jack,visitor
orlando,visitor
这是我当前的bash脚本:

#!/bin/bash

username=username.txt

while IFS=, read username1 group1; do
 if [ $group1 = "visitor" ]; then
   echo $username1 > reportvisitors.txt
 fi
done < $username
实际产量:

jack
您使用的是>而不是>>,在循环的每次迭代期间,它会覆盖该文件中当前的数据。要将文本附加到文件中,需要改用>>。只需按如下方式修改脚本:

!/bin/bash username=username.txt 当IFS=时,读取username1group1;做 echo$username1$group1 如果[$group1==visitor]];然后 echo$username1>>reportvisitors.txt fi 完成<$username 如果此脚本的唯一目的只是收集访客,那么您可以在awk one liner中获得相同的结果,如下所示:

awk-F,“{if$2==visitorprint$1}”username.txt>reportvisitors.txt 您使用的是>而不是>>,在循环的每次迭代期间,它会覆盖该文件中当前的数据。要将文本附加到文件中,需要改用>>。只需按如下方式修改脚本:

!/bin/bash username=username.txt 当IFS=时,读取username1group1;做 echo$username1$group1 如果[$group1==visitor]];然后 echo$username1>>reportvisitors.txt fi 完成<$username 如果此脚本的唯一目的只是收集访客,那么您可以在awk one liner中获得相同的结果,如下所示:

awk-F,“{if$2==visitorprint$1}”username.txt>reportvisitors.txt
将io重定向操作符移动到循环的末尾

#!/bin/bash

username=username.txt

while IFS=, read username1 group1; do
 if [ "$group1" = "visitor" ]; then
   echo "$username1"
 fi
done < "$username" > reportvisitors.txt

将io重定向操作符移动到循环的末尾

#!/bin/bash

username=username.txt

while IFS=, read username1 group1; do
 if [ "$group1" = "visitor" ]; then
   echo "$username1"
 fi
done < "$username" > reportvisitors.txt

首先创建一个临时文件来打印结果。您可以使用mktemp实用程序执行此操作。然后,如果没有发生错误,将该文件移动到reportvisitors.txt。使用>>而不是>附加到临时文件:

#!/bin/bash

username=username.txt
tmpfile=$(mktemp)

while IFS=, read username1 group1; do
    if [ $group1 = "visitor" ]; then
        echo $username1 >> "$tmpfile"
    fi
done < $username

mv "$tmpfile" reportvisitors.txt
这避免了即使脚本因错误而失败,也会丢失reportvisitors.txt以前的内容的问题


理想情况下,脚本应该具有错误处理功能,并在出现错误时删除临时文件。

首先创建一个临时文件以打印结果。您可以使用mktemp实用程序执行此操作。然后,如果没有发生错误,将该文件移动到reportvisitors.txt。使用>>而不是>附加到临时文件:

#!/bin/bash

username=username.txt
tmpfile=$(mktemp)

while IFS=, read username1 group1; do
    if [ $group1 = "visitor" ]; then
        echo $username1 >> "$tmpfile"
    fi
done < $username

mv "$tmpfile" reportvisitors.txt
这避免了即使脚本因错误而失败,也会丢失reportvisitors.txt以前的内容的问题


理想情况下,您的脚本应该具有错误处理功能,并在出现错误时删除临时文件。

请参阅上一个问题的答案。实际上,我的输出表明这是有意义的,因为它是输入文件中的最后一个条目。不使用awk:awk-F,'$2==visitor{print$1>reportvisitors.txt}“$username”如果要每次运行覆盖一次,请在完成后放置>reportvisitors.txt。通过这种方式,您仍然会截断文件,但您会在每个循环中截断一次,而不是在每个echo中截断一次。顺便说一句,这里有很多错误,在撰写本文时,在所有与错误引用相关的建议答案中,请试着测试当访问者的用户名为*时会发生什么。运行代码始终是一个好主意。请参阅上一个问题的答案。实际上,我的输出显示了orlando,这是有意义的,因为它是输入文件中的最后一个条目。是否有理由不使用awk:awk-F,'$2==visitor{print$1>reportvisitors.txt}'$username?如果希望每次运行覆盖一次,将>reportvisitors.txt放在完成后。通过这种方式,您仍然会截断文件,但您会在每个循环中截断一次,而不是在每个echo中截断一次。顺便说一句,这里有很多错误,在撰写本文时,在所有与错误引用相关的建议答案中,请试着测试当访问者的用户名为*时会发生什么。运行代码始终是一个好主意。只需将>reportvisitors.txt移动到“完成”即可使脚本每次运行都从一开始就重写文件。您不需要rm,也不需要切换到>>更好;仍然未解决的bug是OP代码中仍然存在的bug。我仍然建议修复它们——引用$group1、$username`和$username;这样,您就可以在运行时看到输出,而不必等待脚本完成后再执行cat。只需将>reportvisitors.txt移动到“完成”即可使文件在每次运行脚本时从一开始就被重写。您不需要rm,也不需要切换到>>更好;仍然未解决的bug是OP代码中仍然存在的bug。我仍然建议修复它们——引用$group1、$username`和$username;这样,您就可以在运行时看到输出,而不必等待脚本完成后再执行cat。OP不希望多次运行脚本会导致文件具有多组输出。OP不希望 多次运行脚本以使文件具有多组输出。为什么每次要回显一行输出时都重新打开tmpfile?如果只打开一次,那么也不需要从>切换到>>。例如,将exec>$tmpfile放在tmpfile=$mktemp之后,然后默认情况下脚本中的每个回显都将附加到已打开的文件句柄。为什么每次要回显一行输出时都要重新打开tmpfile?如果只打开一次,那么也不需要从>切换到>>。例如,将exec>$tmpfile放在tmpfile=$mktemp之后,默认情况下,脚本中的每个回显都将附加到已打开的文件句柄。