Чому знак "менше" не працює як заміна кішці в башті?


17

Я чув про "марне використання кота" і знайшов кілька пропозицій, але наступні результати нічого не дають у моїй башті.

< filename

Однак використання кота працює, як і очікувалося.

cat filename

Я використовую Fedora Core 18 та GNU bash, версія 4.2.45 (1).

РЕДАКТУВАННЯ: Використання його перед трубою також не працює.

< filename | grep pattern

Тоді як використання кота працює як очікувалося.

cat filename | grep pattern

EDIT2: Для уточнення я знаю, що можу цим скористатися

grep pattern < filename

але я читаю тут /programming/11710552/useless-use-of-cat, що я також можу його використовувати перед командою. Однак він не працює перед командою.


2
Це працює. Тільки те, що ви спробували, не те саме, що пропонує коментар Джонатана Леффлера .
манатурка

"Мета кішки - об'єднати (або" катенувати ") файли. Якщо це лише один файл, об'єднати його взагалі ні з чим - це марна трата часу і коштує вам процесу". partmaps.org/era/unix/award.html
Бонсі Скотт

Відповіді:


22

Символ менше та символ ( <) відкриває файл і приєднує його до стандартної ручки пристрою введення деякої програми / програми. Але ви не надали оболонці жодної програми, до якої можна вкласти вхід.

Приклад

Ці два приклади роблять по суті те ж саме, але отримують свій внесок у 2 дещо різні способи.

відкриває файл

$ cat blah.txt 
hi

відкриває STDIN

$ cat < blah.txt 
hi

Зазирнути за завісу

Ви можете використовувати, straceщоб побачити, що відбувається.

Коли ми читаємо з файлу

open("blah.txt", O_RDONLY)              = 3
fstat(3, {st_mode=S_IFREG|0664, st_size=3, ...}) = 0
fadvise64(3, 0, 0, POSIX_FADV_SEQUENTIAL) = 0
read(3, "hi\n", 65536)                  = 3
write(1, "hi\n", 3hi
)                     = 3
read(3, "", 65536)                      = 0
close(3)                                = 0
close(1)                                = 0

Коли ми читаємо з STDIN (позначається як 0)

read(0, "hi\n", 65536)                  = 3
write(1, "hi\n", 3hi
)                     = 3
read(0, "", 65536)                      = 0
close(0)                                = 0
close(1)                                = 0

У першому прикладі ми бачимо, що catвідкрили файл і прочитали з нього blah.txt,. У другій ми можемо побачити, що catчитає вміст файлу blah.txtчерез дескриптор файлу STDIN, ідентифікований як дескриптор № 0.

read(0, "hi\n", 65536)                  = 3

1
Тож ця розмова про марне використання кота є хибною?
помилка

@bug - ні, є використання. Але, catяк правило, не зрозуміло і використовується, коли це не потрібно.
slm

Але це потрібно, коли я хочу зберегти порядок операцій зліва направо? Я читав, що перед командою можна використовувати і конструкцію, що менша, ніж конструкцію.
помилка

@bug так, перенаправлення може відбутися до або після команди, дивіться відповідь Стефана, він також показує цей приклад.
slm

Ах, тепер я зрозумів. Я мав би написати < filename command.
помилка

14

Класичне марне використання cat це коли ви використовуєте його для введення програм, які ідеально здатні безпосередньо відкривати файли. Наприклад:

Поганий

cat file | grep foo
cat file | while read line; do echo "$line"; done
cat file | sed 's/a/b/'
cat file | awk '{print $1}'

Добре

grep foo file
while read line; do echo "$line"; done < file 
sed 's/a/b/' file
awk '{print $1}' file

Також добре ( <fileможе бути по обидва боки команди)

<file grep foo
 sed 's/a/b/' < file
<file awk '{print $1}' 

6
"Поганий" тут суб'єктивний. Я вважаю, що вони в цілому кращі, тому що це спосіб більш послідовний і легший для читання. І потік даних повністю зліва направо, як це має бути, якщо буде залучено більше труб
Izkata

2
@Izkata вони "погані" в тому сенсі, що вони марні cat.
тердон

"Вниз! Геть зі столу! Ти поганий кіт! ";-) Але серйозно ...
G-Man каже:" Відновіть Моніку "

1
Заслуговує на увагу хороше (або, принаймні, корисне) використання catinclude (1) cat file(з виходом на екран / термінал; хоча, якщо файл довший, ніж екран, високий, ви можете скористатись moreабо використовувати lessщось подібне), (2) cat file1 file2 file3 > all_data( саме те , що catпризначено для), (3) cat f1 f2 f3 | tr …(або передача в будь-яку іншу програму, якій ви не хочете передавати файли безпосередньо; наприклад, wc(наприклад, якщо ви хочете бачити лише загальну суму) або grep(наприклад, якщо у вас є стара версія, яка не підтримує -h, тобто --no-filename)),… (Продовжує)
G-Man каже: «

(Продовження)… (4) cat -n file | sort … -k1 | sed 's/^ *[0-9]*\t//', (5) sudo cat file600 | untrusted_program(тобто ви (ваш UID) не можете прочитати файл, і ви не хочете запускати програму як root або навіть будь-який напівпривілейований UID). Також ( e ) (тобто число між 2 і 3) program_that_generates_html | cat static_html_header - static_html_footer(яке ви, ймовірно, хочете перенаправити на файл або трубу).
G-Man каже: "Відновіть Моніку"

13

UUOC знаходиться в:

cat somefile | some-cmd

або

cat < somefile | some-cmd

Там some-cmdвідбувається зчитування вмісту somefileз каналу, який подається, з catякого він сам читає його somefile.

some-cmdможе читати безпосередньо з somefile(після того, як оболонка відкрила його для stdin), не потрібно cat:

some-cmd < somefile

або

< somefile some-cmd

(перенаправлення можуть з’являтися в будь-якому місці простого командного рядка).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.