Захватить определенное содержимое файла

9

Итак, я знаю, что существуют инструменты для этой проблемы, потому что я слышал о них, но я не знаю, что это такое.

Я хочу сделать что-то вроде отфильтровать все данные, кроме имен пользователей в / etc / passwd.

Например, я хотел бы получить user1, user2 и user3 из следующего файла. В этом случае логика может быть «Захватывать текст до первого символа«: »в каждой строке файла».

user1:x:1:4
user2:x:2:5
user3:x:3:6

Выход будет:

user1
user2
user3
Муш
источник

Ответы:

19

cutсуществует именно для этой цели. -dФлаг указывает разделитель, и -fопределяет , какие поля для вывода:

cut -d: -f1 /etc/passwd

Аргументом для -fможет быть что-то вроде 1,3отображения первого и третьего полей или 1-3отображения первых трех; Есть также -bи -cфлаги для чтения байтов и символов вместо полей. Если вам нужно что-то более гибкое, обычно awkсработает (см . Ответ Мэтью )

Михаил Мрозек
источник
13

Каждый раз, когда вы хотите извлечь данные из табличного ввода, вы должны рассмотреть awk . Он доступен практически на каждой системе Unix, поэтому стоит взять:

awk -F':' '{print $1}' /etc/passwd 
  • -F':': определяет ":" как разделитель столбцов.
  • '{}': выполнить эту инструкцию для каждой строки.
  • print $1: вывести первый столбец на экран.
Мэтью Бранниган
источник
3
Случайная заметка: awkберет имя файла, так что вы можете пропустить канал и просто сделатьawk -F: '{print $1}' /etc/passwd
Майкл Мрозек
Кажется, я всегда забываю, что awk берет имя файла, я всегда использую его в конвейере ... что-то вроде sed | awk и т.д ...
Мэтью Бранниган
почти все, что работает с файлами, принимает имя файла ( trи atявляется парой примеров из нескольких вещей, которые этого не делают).
Приостановлено до дальнейшего уведомления.
3

Вот Perl с одним вкладышем:

perl -F/:/ -lane 'print $F[0]' /etc/passwd
Зайд
источник
1

Под perl и awk есть третий инструмент для таких работ, который sed:

sed 's/:.*//' FILE 

Это команда подстановки: замена от двоеточия:, за которой следует точка, которая является джокером для символов любого типа, любого количества (*), без нуля.

Это (ubstitute) / FROM / TO / 'с пустым значением TO, что означает' удалить все с первого (поскольку по умолчанию sed является жадным) двоеточия (до конца строки, поскольку sed хорошо работает со всеми строками).

Конечно, cutэто хорошая команда, но я бы сказал, из другой семьи.

Пользователь неизвестен
источник
1

В вашем примере все 3 имени имеют одинаковую длину. В таких случаях - что может случиться, но не так часто с / etc / passwd - вы также можете использовать colrm:

echo "user1:x:1:4
> user2:x:2:5
> user3:x:3:6" | colrm 6
user1
user2
user3

или, конечно

cat FILE | colrm 6 

(редкий случай, когда useless use of catэто не применимо, потому что вы не можете передать файл FIL в качестве параметра.)

Пользователь неизвестен
источник
catтам все еще бесполезно colrm 6 < FILE.
manatwork
Ну да, но не так бесполезно, как при звонке cat foo | grep bar.
пользователь неизвестен
1

Просто для полноты, нет необходимости во внешних командах, оболочка (Bourne или совместимая) может обрабатывать ее самостоятельно:

while IFS=':' read -r needed garbage; do echo "$needed"; done < input_file

Конечно, это, вероятно, самое медленное из всех возможных решений, поэтому для огромных файлов выберите другое.

manatwork
источник