我需要将用户列表()与帐户的 .csv 文件进行比较,并从中获取不在我的 csv 文件中的/etc/passwd
帐户。/etc/passwd
/etc/passwd
显示:
root:x:0:0:root:/root:/bin/bash
albert:x:521:521:auto:/home/albert:/bin/bash
alfred:x:521:521:auto:/home/alfred:/bin/bash
.csv
文件显示:
albert,abc123
预期输出为:
root
alfred
我使用 awk 和 grep 尝试了两天,但结果不是我想要的。
答案1
grep
、tr
和cut
过程替换的组合:
cut -d: -f1 /etc/passwd | grep -xvFf <(tr ',' '\n' < file.csv)
该命令从(第一个-delimited 字段)cut
获取用户名。/etc/passwd
:
然后,该tr
命令将您的 CSV 字段转换为每行一个用户名。
然后,grep 命令会从包含模式的文件中查找-x
不匹配 ( -v
) 任何固定模式 ( ) 的整行 (),每行一个 ( )。我们使用进程替换 ( ) 来使用这些模式的输出。-F
-f
<()
tr
答案2
不如 muru 的解决方案那么顺利,但可以使用另一种方法comm
,tr
以及cut
和sort
:
comm -13 <(<file tr ',' '\n' | sort) <(cut -d ':' -f 1 /etc/passwd | sort)
comm -13 <(<file tr ',' '\n' | sort) <(cut -d ':' -f 1 /etc/passwd | sort)
<file tr ',' '\n' | sort
: 比较和输出中的行,cut -d ':' -f 1 /etc/passwd | sort
并仅打印独有的行cut -d ':' -f 1 /etc/passwd | sort
;<file tr ',' '\n' | sort
:从 读取 STDINfile
,将逗号转换为换行符并对输出文件进行排序;cut -d ':' -f 1 /etc/passwd | sort
:打印每行第一个以冒号分隔的字段并对/etc/passwd
输出文件进行排序;
另一种方法是使用combine
(在moreutils
包中sudo add-apt-repository universe && sudo apt-get update && sudo apt-get install moreutils
:),这样可以保存几个sort
命令(尽管很可能combine
在内部对文件进行排序):
combine <(cut -d ':' -f 1 /etc/passwd) NOT <(<file tr ',' '\n')
combine <(cut -d ':' -f 1 /etc/passwd) NOT <(<file tr ',' '\n')
cut -d ':' -f 1 /etc/passwd
: 比较和输出中的行,<file tr ',' '\n'
并仅打印独有的行cut -d ':' -f 1 /etc/passwd
;<file tr ',' '\n'
:从 STDIN 读取file
并将逗号转换为换行符;cut -d ':' -f 1 /etc/passwd
/etc/passwd
: 打印;中每行第一个以冒号分隔的字段