Как объединить префикс для вывода ls в bash? - PullRequest
2 голосов
/ 12 октября 2019

Допустим, у меня есть несколько изображений в родительском каталоге: ../imagea/a.png и ../images/b.png.

Когда я делаю:

ls ../images

# I get
../images/a.png
../images/b.png

Как добавить префикс ![]( и суффикс ) для всех этих выходов?

Я пытался:

!ls ../images/*.png | cat

# am not sure what to do next

Обязательный вывод

![](../images/a.png)
![](../images/b.png)

Справкаоценили.

Ответы [ 4 ]

2 голосов
/ 13 октября 2019

Самое простое решение - использовать стандартную команду posix find с действием printf, например:

 find ../images -name "*.png" -printf '![](%p)\n'

Объяснение:

../images - целевой каталог

"*.png" - шаблон глобуса

-printf - форматировать действие для вывода

'![](%p)\n' - форматировать аргументы для вывода полного пути.

Пример:

$ ls -l
total 8
drwxrwxr-x.  3 cfrm cfrm   15 Dec 13  2018 app
drwxrwxr-x.  2 cfrm cfrm   23 Mar 24  2019 app_5811_install
drwxrwxr-x. 13 cfrm cfrm 4096 Dec 12  2018 app_58_install
drwxrwxr-x.  2 cfrm cfrm 4096 Oct  3  2018 grants
-rwx------.  1 cfrm cfrm  526 Feb 17  2019 ic_start_all.sh
-rwx------.  1 cfrm cfrm  920 Oct  4  2018 ic_status_all.sh
-rwx------.  1 cfrm cfrm  984 Sep 27  2018 ic_stop_all.sh
-rwxrwxr-x.  1 cfrm cfrm 1693 Dec 13  2018 loadTrigger.sh



$ find . -name "*.sh" -printf '![](%p)\n'
![](./ic_stop_all.sh)
![](./ic_status_all.sh)
![](./loadTrigger.sh)
![](./ic_start_all.sh)
2 голосов
/ 12 октября 2019

Выполните цикл над шаблоном глобуса и напечатайте каждую строку, отформатированную по желанию:

for filename in ../*.png; do echo '!'"[]($filename)"; done
1 голос
/ 12 октября 2019

Во-первых, я не верю тебе. ls ../images будет выводить только базовые имена, например:

a.png
b.png
...etc...

A разные команда ls ../images/* может дать вывод, который вы показываете.

Хотя в системе, использующей ls из GNU coreutils, например, в Linux, если выводом является терминал и , имена файлов короткие, как вы показали, ls без параметров подойдетвывод в виде нескольких столбцов больше похож на:

../images/aaaaa.png   ../images/ddddd.png  ../images/ggggg.png
../images/b.png       ../images/eeeee.png  ../images/hhhhhh.png
../images/ccccc.png   ../images/f.png      ../images/iiiiii.png

, если у вас нет псевдонима (или функции или сценария теневого копирования), который заставляет опцию -1 (one) предотвратить это. Или фактические имена (значительно) длиннее, как они, вероятно, должны быть. Или вы что-то пускаете, даже cat, потому что тогда вывод ls - это труба, а не терминал. Эти детали имеют значение.

В некоторых случаях sed так же хорош, как awk, и обычно более краткий:

ls | sed 's/^/![](/; s/$/)/'
# sed processes a string of command(s) for each line read from stdin, 
# and writes the result to stdout (by default, -n overrides this)
# s/old/new/ is string replacement using regex (which can be complex)
# ^ in old matches the beginning of the line
# $ in old matches the end of the line

# this assumes none of your filenames contains a newline character
# which Unix permits, but is rarely done because it is quite confusing

или , так как вам нравится printf может выполнять всю работу:

printf '![](%s)\n' ../images/*
# printf takes a format string containing any mixture of literal text 
# (including backslash+letter escapes mostly the same as C et succ)
# and conversion specifiers beginning with % which each interpolate one argument
# it repeats the format as needed to handle all the arguments, so here 
# with one c.s. it repeats the format once for each argument = filename

# this 'works' even if a filename contains newline
# (but I don't think the result will work correctly as markdown)
1 голос
/ 12 октября 2019

Не могли бы вы попробовать следующее.

awk 'BEGIN{for(i=1;i<ARGC;i++)print "![](..",ARGV[i]")"}' ../images/*.png

Вывод будет следующим (где a, b, c ... .png - тестовые файлы, созданные мной для целей тестирования).

![](.. ../images/a.png)
![](.. ../images/b.png)
![](.. ../images/c.png)
![](.. ../images/d.png)
...