替换文本文件中一行中的字段

时间:2014-08-04 03:15:57

标签: bash

我试图grep第三个字段并将其替换为位于文本文件中的特定行。文本文件格式如下:

username:password:access level:failed password attempts

我知道如何grep整行并将其显示在文本文件中,但我不确定如何查找和替换第三个字段。

我是bash的新手,很抱歉。

输入的一个例子是:

"Change access level to : "
User enters in Restricted.

输出将是:     以前:

admin:password:Granted Access

Now :
admin:password:Restricted

用户只需输入他想要的访问级别,并在文本文件中更改特定用户和密码的访问级别。

1 个答案:

答案 0 :(得分:0)

基本上就是这样的。您使用awk

read -p "Enter username: " username
read -p "Enter access level: " access
temp_file=$(mktemp)
awk -v username="$username" -v acccess="$access" -F : -v OFS=: '$1 == username { $3 = access } 1' password_file.txt > "$temp_file"
cat "$temp_file" > password_file.txt
rm -f "$temp_file"
  • -F :将字段分隔符设置为:
  • -v OFS=:将输出字段分隔符设置为:
  • $1 == username检查第一个字段是否与用户名匹配。
  • $3 = access将第3个字段的值更改为access的值。
  • 1基本上命令打印当前记录(行)。
  • temp_file=$(mktemp)创建一个临时文件
  • cat "$temp_file" > password_file.txt将更改写回来。
  • rm -f "$temp_file"删除临时文件。

根据密码进行匹配:

awk -v username="$username" -v password="$password" -v acccess="$access" -F : -v OFS=: '$1 == username && $2 == password { $3 = access } 1' password_file.txt > "$temp_file"

这是Bash的解决方案,其中不需要临时文件:

[[ BASH_VERSINFO -ge 4 ]] || exit 1
read -p "Enter username: " username
read -p "Enter access level: " access
readarray -t new_data < <(exec awk -v username="$username" -v acccess="$access" -F : -v OFS=: '$1 == username { $3 = access } 1' password_file.txt)
printf '%s\n' "${newdata[@]}" >password_file.txt
  • [[ BASH_VERSINFO -ge 4 ]] || exit 1确保我们使用的是Bash 4.0或更新版本。
  • readarray -t new_data将输出行保存到数组new_data
  • printf '%s\n' "${newdata[@]}" > password_file.txt将数据从数据写回文件。

这是readarray的替代方案。它只需要Bash 3.1或更新版本。

new_data=()
while IFS= read -r line; do new_data+=("$line"); done < <(exec awk -v username="$username" -v acccess="$access" -F : -v OFS=: '$1 == username { $3 = access } 1' password_file.txt)

对于支持数组的早期版本,new_data=("${new_data[@]}" "$line")也可以应用,但效率较低。