LINUX.ORG.RU

bash: Вывод содержимого файлов, с именем файла.

 ,


1

2

Хотелось бы получить содержимое на экран всех файлов по шаблону в формате: имя файла + содержимое

Использую это tail *.txt и такое a=`ls *.txt` ; for i in $a ; do echo «$i»; cat $i ; done

Может все таки можно сделать элегантнее?

Ответ на: комментарий от anonymous

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

anonymous
()

Я не знаком с вашими понятиями об элегантности, но вот это:

a=`ls *.txt`

злостная ошибка.

Zmicier ★★★★★
()
Ответ на: комментарий от ssizziff

элегантнее

grep . *.txt

да спасибо!

Ага, уловил, элегантно для вас — это по гвоздям микроскопом. :-)

Zmicier ★★★★★
()
Ответ на: комментарий от Zmicier

ну а= может быть любым. (ну да я пока что новичек в баше) может как то все таки с пайпами можно замутить про find совсем не понял...

ssizziff
() автор топика
Ответ на: комментарий от ssizziff

ну а= может быть любым

Не поможет, там дальше еще две злостные ошибки:

for i in $a
cat $i

(ну да я пока что новичек в баше)

Тем более идите читать руководства, а не прививайте себе привычку писать дурно. Так, если вы новичок именно в Баше (то есть в принципе писать программы умеете), то смело начинайте с «GNU Bash Pitfalls» под редакцией Вулиджа.

Zmicier ★★★★★
()
Последнее исправление: Zmicier (всего исправлений: 1)
Ответ на: комментарий от ssizziff

да спасибо!

Рано вы спасибо говорите. Мало того, что это полный ужас, так оно ещё не рабочее для пустых строк и если файл только один. Ну пусть будет вредный совет:

grep -H '.*' *.txt

vodz ★★★★★
()
Последнее исправление: vodz (всего исправлений: 2)
Ответ на: комментарий от ssizziff

Но эта вечная проблема: вместо ответа давать советы...

Проблемы плодят как раз анонимы «ответами» типа $ grep . *.txt.

Если вы, прочтя брошюрку, что я вам посоветовал — на это уйдет где-то минут пятнадцать, не сможете сами написать ответ с правильным (и вполне элегантным, имхо) решением на Баше, я на сегодня разочаруюсь в этом мире.

Zmicier ★★★★★
()
Последнее исправление: Zmicier (всего исправлений: 1)
Ответ на: комментарий от art_metr

Ну помилуйте! Товарищ же показал свой черновик, и он ясно предполагает вывод лишь файлов из рабочего каталога.

Да и нет в Баше find’а :-).

Zmicier ★★★★★
()
Ответ на: комментарий от Zmicier

Всё равно не правильно, у меня имя следующего файла сразу за последним символом содержимого предыдущего печатает... Параметры find пусть сам изучает.

art_metr
()
Ответ на: комментарий от Zmicier

>Да и нет в Баше find’а :-).

Для меня его вообще нет))) Почему-то всегда у меня с ним косяки получаются. Предам его анафеме, циклы наше всё.

art_metr
()
Ответ на: комментарий от Zmicier

Нее... я за работу всего примера. Пока не научил /dev/random проставлять \n в файлах))

art_metr
()
Ответ на: комментарий от art_metr

Больше нюансов — богу нюансов, больше косяков — к трону косяков!

for f in *.odt; do echo "$f"; cat "$f"; echo; done

$ echo 'foo bar' > -README-.odt
$ for f in *.odt; do echo "$f"; cat "$f"; echo; done
-README-.odt
cat: invalid option -- 'R'
Try 'cat --help' for more information.

Zmicier ★★★★★
()
Последнее исправление: Zmicier (всего исправлений: 2)
Ответ на: комментарий от art_metr

Баш

Ну в данном случае это cat(1) :-)

На Баше (в смысле на echo) споткнуться на этом примере, кажется, уже нельзя, — нужен файл -n или -e.

Zmicier ★★★★★
()
Ответ на: комментарий от Zmicier
touch -- -n.txt some.txt && for f in *.txt ; do echo -E -- "$f" -- && cat -- "$f" ; done

-- -n.txt --

-- some.txt --

Разумеется, имя файла будет искажено. Кстати,

echo "$f"
тоже работает

anonymous
()
Ответ на: комментарий от Zmicier

Классик лор, пока оп уже всё сделал вариантом из первого поста, лоровцы всё писали корректный вариант.

anonymous
()
Ответ на: комментарий от anonymous

Так выше писали про то, почему насчет первого поста справедливо кг/ам

anonymous
()
Ответ на: комментарий от art_metr

Про — знаю. Баш можно одной фразой охарактеризовать «туда босиком не ходи, там мины»...

А вот cat файла.odt (из bash: Вывод содержимого файлов, с именем файла. (комментарий) ) — это тоже косяк баша? Что вы при этом ожидаете получить? Сломанную консоль? Фaйл, который ничем потом не распарсить?

vodz ★★★★★
()
Ответ на: комментарий от vodz

Зря вы так. У меня, например, работает

anonymous
()
Ответ на: комментарий от anonymous

-- -n.txt --

А теперь можете проверить и без -- :-)

Кстати echo "$f" тоже работает

Внезапно! Можете подняться чуть выше и посмотреть, когда не будет. Но я еще -E там не назвал, да.

Zmicier ★★★★★
()
Последнее исправление: Zmicier (всего исправлений: 1)
Ответ на: комментарий от KennyMinigun

Если правда зачем-то хочется использовать find(1) вместо шелла, то как-то так, что ли:

$ find -maxdepth 1 -type f -name '*.txt' -print -exec cat {} \; -printf '\n'
Zmicier ★★★★★
()
Ответ на: комментарий от art_metr

Так-то этот пример работает. В чём подвох?

Вы получите то, о чём и были вопросы: или не рабочую консоль после бинарного вывода odt-файла, или, если перенаправите вывод в файл, то получите файл, который ничем толком не распарсите: вам по новой придётся выкусывать «текстовое» имя файла из первой строки полученного файла, а бинарный остаток сохранять в odt.

vodz ★★★★★
()
Ответ на: комментарий от Zmicier

Проще всё же: -name '[^.]*.txt' Ну и "-and" у вас и так по умолчанию всюду юзается, зачем вы там его написали явно?

Такие маски легко на всю жизнь запомнить как сочинять, когда программируешь что-то на sh из серии: «узнать, что аргумент число». Так как это преобразуется в ужас из серии

    case "$1" in
    "" | *[![:digit:]]* ) return 1;;
    esac

vodz ★★★★★
()
Последнее исправление: vodz (всего исправлений: 3)
Ответ на: комментарий от Zmicier

Спокойно :) Я лишь показал базовый пример. Догнать дополнительными флагами всегда успеется ;)

KennyMinigun ★★★★★
()
Ответ на: комментарий от vodz

Проще всё же: -name '[^.]*.txt'

Чем?

Ну и "-and" у вас и так по умолчанию всюду юзается, зачем вы там его написали явно?

Именно для того, чтобы не прибегать к умолчаниям.

Zmicier ★★★★★
()
Ответ на: комментарий от KennyMinigun

Вах, не знал, что case умеет в регулярки

И правильно делали. :-)

Zmicier ★★★★★
()
Ответ на: комментарий от KennyMinigun

Вах, не знал, что case умеет в регулярки (а не только в wildcard), спасибо

Увы, это таки wildcard.

vodz ★★★★★
()
Ответ на: комментарий от Zmicier

Чем?

Тем, что не надо вспоминать приоритет -and -not и вообще короче.

Именно для того, чтобы не прибегать к умолчаниям.

Чё? Ах, ну да, это же Zmicier. Он не может не начать паясничать. То есть вы опустили 5 умолчаний:

find -maxdepth 1 -and -type f -and -name '*.txt' -and -not -name '.*' -and -print -and -exec cat {} \; -and -printf '\n'
а одно написали «чтобы не прибегать к умолчаниям.» Ну да, типично по Zmicier-ски.

vodz ★★★★★
()
Ответ на: комментарий от vodz

И все это что бы быстро глянуть что внутри однотипных конфигов ... :)

ssizziff
() автор топика
Ответ на: комментарий от pacify

Ну, в гугле по «linux cat with filename» выдаётся такой способ:

Ради поизвращаться, оно конечно, прикольно. Но способ не очень: формат verbose не специфицирован. Да даже, если он будет вечно таким «==> %s <==», то вырезать ненужные символы окажется сложнее, чем применить вышеуказанные способы.

vodz ★★★★★
()
Ответ на: комментарий от pacify

А мне такой способ полезен.

Я речь вёл не о том. У вас же не основная работа «Быстро посмотреть контент с подписями (имя файла)»? Потому через неделю вы этот способ забудете, а с find/for можно понять не запоминая, так как это будет просто крупинка в копилку умений работы с sh, которые при его использовании всегда будут не давать забыть.

vodz ★★★★★
()
Ответ на: комментарий от vodz

Да не проблема написать find + xargs, просто я дал решение задачи ТС. В 99% случаев он подходит.

pacify ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.