增加和修改列表中的数字

Incrementing and modifying numbers on list

我正在尝试编写一个脚本作为注册表的一部分。一切都已准备就绪,但是,我想实现一个类似于 UID 在 bash 中的工作方式的 "UID" 函数。然而,这是棘手的部分:每次添加用户时,我要实施的 UID 都会增加 1,如果该用户删除他/她的帐户,他的帐户将从数据库中删除,从而删除用于他的 UID。我想要用来检查现有 UID 的脚本,如果有差异,它会填充它。

示例

Name:UID

Apple:0001
Bag:0002
Cat:0003
Dog:0004

Cat 删除了他的帐户,因此新列表将是

Apple:0001
Bag:0002
Dog:0004

如果新用户创建了一个帐户,它应该是

Apple:0001
Bag:0002
NEWUSER:0003
Dog:0004

一切都已修复,包括从数据库中删除帐户我只是在实现 UID 的增量及其填充缺失数字的能力方面遇到了问题。非常感谢您的帮助!非常感谢!

编辑:我大致知道在将它们放入循环结构时要使用什么,例如 sed 和 cmp,但还不足以将它们变成我想要的东西。

维护一个空闲索引列表(一个数组),如果有空闲索引,则使用它来查找空闲索引:

declare -a free_indexes=()
...
if [[ action == "remove" ]]; then
    free_indexes=( ${free_indexes[@]} $removed_index )
elif [[ action == "add" ]]; then
    if [[ ${#free_indexes[@]} -ne 0 ]]; then
        index=${free_indexes[0]}
        unset free_indexes[0]
        free_indexes=( ${free_indexes[@]} )
    else
        index=next_index
    fi
fi

awk 解决办法:

假设关键文件名为 users,在 Cat 删除他的帐户后具有以下内容:

Name:UID
Apple:0001
Bag:0002
Dog:0004

awk -v nuser="NEWUSER" -F':' 'NR>1 && uid && (int()-uid>1){ 
           [=11=]=sprintf("%s:%04d\n%s",nuser,uid+1,[=11=]) }
           { uid=int() }1' users > tmp$$ && mv tmp$$ users

users 处理后的文件:

Name:UID
Apple:0001
Bag:0002
NEWUSER:0003
Dog:0004

假设 uids.txt 存在

cat uids.txt
Apple:0001
Bag:0002
Dog:0004

您可以使用 bash-fun 库以功能方式完成您的工作:)

source <(curl -Ls https://raw.githubusercontent.com/ssledz/bash-fun/master/src/fun.sh)

next_id() {
  prepend $(tup 0 0) | cut -d':' -f2 \
  | map lambda a . 'echo $((a))' |  sort \
  | scanl lambda acc el . 'cnt=$(tupl $acc); cnt=$((cnt+1)); tup $cnt $el' \
  | filter lambda a . 'cnt=$(tupl $a); el=$(tupr $a); [[ $cnt -ne $a ]] && ret true || ret false' \
  | tupl | fold -w 1 | append 0 0 0 0 | take 4 | revers | join ''
}

echo NEWUSER:$(cat uids.txt | next_id) | cat - uids.txt |sort -t ':' -n -k2

你应该在return得到

Apple:0001
Bag:0002
NEWUSER:0003
Dog:0004

在这里你可以找到我关于这个库的介绍:fun.sh

无论输入文件的顺序如何、有多少间隙或这些间隙有多大,这都有效:

$ cat addUser.awk
BEGIN { FS=OFS=":"; min=max=1 }
NR==1 { print; next }
{
    uid = +0
    uid2user[uid] = 
    min = (min > uid ? uid : min)
    max = (max < uid ? uid : max)
}
END {
    fmt = "%s" OFS "%04d\n"
    for (uid=min; uid<=max; uid++) {
        if (uid in uid2user) {
            printf fmt, uid2user[uid], uid
        }
        else if (newUser != "") {
            printf fmt, newUser, uid
            newUser = ""
        }
    }
    if (newUser != "") {
        printf fmt, newUser, uid
    }
}

.

$ cat users1
Name:UID
Cat:0003
Apple:0001
Dog:0004
Bag:0002

$ awk -v newUser="NEWUSER" -f addUser.awk users1
Name:UID
Apple:0001
Bag:0002
Cat:0003
Dog:0004
NEWUSER:0005

$ cat users2
Name:UID
Bag:0002
Dog:0004
Apple:0001

$ awk -v newUser="NEWUSER" -f addUser.awk users2
Name:UID
Apple:0001
Bag:0002
NEWUSER:0003
Dog:0004

$ cat users3
Name:UID

$ awk -v newUser="NEWUSER" -f addUser.awk users3
Name:UID
NEWUSER:0001

.

$ cat users4
Name:UID
Bag:0002
Dog:0004
Apple:0001
Frog:0006

$ awk -v newUser="NEWUSER" -f addUser.awk users4
Name:UID
Apple:0001
Bag:0002
NEWUSER:0003
Dog:0004
Frog:0006

$ cat users5
Name:UID
Bag:0002
Apple:0001
Frog:0006

$ awk -v newUser="NEWUSER" -f addUser.awk users5
Name:UID
Apple:0001
Bag:0002
NEWUSER:0003
Frog:0006

考虑到您的 Input_file 与显示的示例相同,因此我在这里考虑了您的陈述 2 种情况。 假设我们有以下 Input_file:

cat Input_file
Name:UID
Apple:0001
Bag:0002
Dog:0004
Billi:0016
ascs:0018
ewdwdwd:0022
qce:0023
ooidw:24
fewfewf:30

1st: 当只有 1 个名为 NEW_USER 的用户时,您必须在所有地方输入,那么以下内容可能会对您有所帮助。

awk -v new="NEW_USER" -F":" '
NR==+1;
NR!=+1{
   q=NR-1;
   while(q<){
     q=sprintf("%04d",q);
     print new":"q;
     q++
};
   NR=q+1;
   print
}'  Input_file

输出如下。

Name:UID
Apple:0001
Bag:0002
NEW_USER:0003
Dog:0004
NEW_USER:0005
NEW_USER:0006
NEW_USER:0007
NEW_USER:0008
NEW_USER:0009
NEW_USER:0010
NEW_USER:0011
NEW_USER:0012
NEW_USER:0013
NEW_USER:0014
NEW_USER:0015
Billi:0016
NEW_USER:0017
ascs:0018
NEW_USER:0019
NEW_USER:0020
NEW_USER:0021
ewdwdwd:0022
qce:0023
ooidw:24
NEW_USER:0025
NEW_USER:0026
NEW_USER:0027
NEW_USER:0028
NEW_USER:0029
fewfewf:30

2nd: 如果你有像 new_user1、new_user2 等这样的用户数量(我从你的陈述中预测您提到了很多缺失的用户,以防您在 sheet).

中有多个用户需要更新
awk -v new="NEW_USER,NEW_USER1,NEW_USER2,NEW_USER3" -F":" 'BEGIN{
len=split(new, a,",")
}
NR==+1;
NR!=+1{
   q=NR-1;
   while(q<){
      q=sprintf("%04d",q);
      if(i==len){
        i=""
};
      print a[++i]":"q;
      q++
};
   NR=q+1;
   i="";
   print
}'   Input_file

输出如下。

Name:UID
Apple:0001
Bag:0002
NEW_USER:0003
Dog:0004
NEW_USER:0005
NEW_USER1:0006
NEW_USER2:0007
NEW_USER3:0008
NEW_USER:0009
NEW_USER1:0010
NEW_USER2:0011
NEW_USER3:0012
NEW_USER:0013
NEW_USER1:0014
NEW_USER2:0015
Billi:0016
NEW_USER:0017
ascs:0018
NEW_USER:0019
NEW_USER1:0020
NEW_USER2:0021
ewdwdwd:0022
qce:0023
ooidw:24
NEW_USER:0025
NEW_USER1:0026
NEW_USER2:0027
NEW_USER3:0028
NEW_USER:0029
fewfewf:30