sed / grep - отобразить 1-й и 5-й столбцы, убрать запятую в 5-м столбце и поменять местами Last-First, и отсортировать в алфавитном порядке по фамилии в / etc / passwd - PullRequest
0 голосов
/ 25 марта 2020

Мне нужна помощь sed / grep с моим /etc/passwd файлом. Пример вывода в моем файле / etc / passwd:

username1:x:5687:3794:Smith, Mike:/home/username1:/bin/bash

Мой первый столбец - имена пользователей, а пятый столбец - Фамилия, Имя, и он никак не в алфавитном порядке. Мне нужно отобразить первый столбец, а затем отобразить пятый столбец в поле Имя Фамилия, отсортированные в алфавитном порядке по фамилии.

У меня есть команда sed для отображения пятого столбца в Имя Фамилия, отсортированная в алфавитном порядке по фамилии:

grep "$userid" /etc/passwd | cut -d: -f5 | sort | sed 's/^\(.*\), \(.*\)$/\2 \1/'

, но простое добавление f1,5 в мою команду вырезать не дает Чтобы получить ожидаемый результат, он удаляет алфавитный порядок и просто помещает первый столбец после их имени, а это не то, что я ищу.

Я могу использовать только команду sed. Что мне нужно, и мне нужна помощь:

grep "$userid" /etc/passwd | cut -d: -f1,5 | sort | sed

Я застрял здесь, так как мало знаю о команде sed, userid - это просто переменная, которую я читаю из пользовательского ввода внутри скрипта для первый столбец.

Таким образом, выходной пример будет:

username7    Abe Adams
username2    Jack Adams
username4    Ben Fab
username5    Jon Heat

Ответы [ 4 ]

1 голос
/ 25 марта 2020

Предполагая, что вы хотите сопоставить несколько пользователей с "идентификатором пользователя", который вы ищете, и что вы хотите, чтобы это была строка, а не сравнение регулярных выражений, вот как это сделать надежно:

$ awk -F':' -v userid='username' 'index($1,userid){n=split($5,names,/[ ,]+/); print $1, names[n], names[1]}' file |
    sort -k3
username1 Mike Smith

I ' m используя split () таким образом, чтобы команда работала, даже если у вас есть более 2 частей на ваше имя (например, Билли Боб Торнтон).

0 голосов
/ 25 марта 2020

Это заняло у меня большую часть дня, и, похоже, я уже опоздал. : (

В любом случае, вот мое решение: -

Файл + .txt: -

username1:x:5687:3794:Smith, Mike:/home/username1:/bin/bash
username2:x:5687:3794:Smith, Bill:/home/username1:/bin/bash
username3:x:5687:3794:Smith, Sam:/home/username1:/bin/bash
username4:x:5687:3794:Smith, Bob:/home/username1:/bin/bash
username5:x:5687:3794:Smith, Steve:/home/username1:/bin/bash

Скрипт + .txt: -

#!/bin/sh -x

init() {
IFS=":"

cat > edpop+.txt << EOF
1d
wq
EOF

cat > edcommands+.txt << EOF
1p
W tmp2+.txt
q
EOF

next
}

end () {
sort -r tmp+.txt > report+.txt
rm -v ./edcommands+.txt
rm -v ./edpop+.txt
IFS=" "
exit 0
}

next() {
[[ -s file+.txt ]] && main
end
}

main() {
ed -s file+.txt < edcommands+.txt
read var1 var2 var3 var4 var5 var6 var7 < tmp2+.txt

lastname=$(echo "${var5}" | cut -d',' -f1)
firstname=$(echo "${var5}" | cut -d',' -f2)
echo -e "${var1}\t${firstname} ${lastname}" >> tmp+.txt
ed -s file+.txt < edpop+.txt
rm -v ./tmp2+.txt
next
}

init

a } Каждая строка первоначально читается с помощью ed.

b} Чтение и IFS используются для разделения каждой строки на переменные с двоеточием в качестве разделителя.

c} Cut используется для вырезания вверх по полям имени / фамилии.

d} Эхо отправляет вновь созданные строки во временный файл.

e} Для временного файла выполняется обратная сортировка, а результат отправляется в report + .txt.

f} Ed используется для удаления первой строки из входного файла, таким образом уменьшая счет на единицу.

g} Сбрасывается l oop. Когда все строки были вытолкнуты из стека на основе входного файла, мы выходим.

0 голосов
/ 25 марта 2020

Хорошо, вот комбинация awk и sort, которая может быть вам полезна:

sort -t: -k5,5 /etc/passwd | awk -F'[: ,]*' '{print $1,$6,$5 }' 
0 голосов
/ 25 марта 2020

Вы получаете двоеточие, разделяющее два поля, если вы используете cut -d: -f1,5, поэтому вы пишете свой скрипт sed, ожидая, что:

grep "$userid" /etc/passwd |
cut -d: -f1,5 |
sed 's/^\([^:]*\):\([^,]*\),[[:space:]]*\(.*\)$/\1  \3 \2/' |
sort -k3,3 -k2,2

Классы отрицанных символов - это полезный способ разделения полей , Обратите внимание, что если запись пароля не содержит запятой (и ни одна из учетных записей в файле паролей на моем компьютере не содержит), то данные передаются через sed без изменений. Вы можете обойти это при необходимости (с большим количеством опций и вторым s/// выражением), но не ясно, что это необходимо.

Также не ясно, почему вам нужно сортировать, если значение в $userid - это своего рода регулярное выражение, которое соответствует нескольким строкам в файле паролей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...