2015-06-25 2 views
1

Это упрощенный пример, который, надеюсь, иллюстрирует мою проблему.File globbing без разделения слов?

У меня есть сценарий, который принимает параметр, который будет использоваться в качестве подстановочного знака. Иногда этот шаблон содержит пробелы. Мне нужно иметь возможность использовать подстановочный знак для globbing, но расщепление слов приводит к сбою.

Например, рассмотрим следующий пример файла:

$ ls -l "/home/me/dir with whitespace" 
total 0 
-rw-r--r-- 1 me  Domain Users 0 Jun 25 16:58 file_a.txt 
-rw-r--r-- 1 me  Domain Users 0 Jun 25 16:58 file_b.txt 

Мой сценарий - упрощена, чтобы использовать жесткий кодированный переменную шаблона - выглядит следующим образом:

#!/bin/bash 

# Here this is hard coded, but normally it would be passed via parameter 
# For example: pattern="${1}" 
# The whitespace and wildcard can appear anywhere in the pattern 
pattern="/home/me/dir with whitespace/file_*.txt" 

# First attempt: without quoting 
ls -l ${pattern} 

# Result: word splitting AND globbing 
# ls: cannot access /home/me/dir: No such file or directory 
# ls: cannot access with: No such file or directory 
# ls: cannot access whitespace/file_*.txt: No such file or directory 


#################### 

# Second attempt: with quoting 
ls -l "${pattern}" 

# Result: no word splitting, no globbing 
# ls: cannot access /home/me/dir with whitespace/file_*.txt: No such file or directory 

Есть ли способ включить глобирование , но отключить разбиение слов?
Есть ли у меня какие-либо опции, кроме того, что я вручную удалял пробелы в моем шаблоне?

+0

Как насчет того, чтобы избежать пробелов? 'pattern =" $ {pattern ///\\} '. Вам нужно будет избегать других значимых символов (например,'; '), поэтому я не рекомендую это самостоятельно! –

+0

Is' ''$ {pattern // \ */\ '* \'} '"любая помощь? Одиночная кавычка всей строки, а затем замените' * 'на' '*'', чтобы вернуть их за строку. Возможно, нужно сделать то же самое с '? 'тоже. –

+0

@TobySpeight - я попытался избежать пробелов. Он по-прежнему становится жертвой расщепления слов, потому что' \\ 'воспринимается буквально потому, что находится внутри переменной. Второе предложение не срабатывало, поскольку оно принимает' ''буквально. –

ответ

0

Я, наконец, получил его!

Уловка модифицирует internal field separator (IFS), чтобы быть пустым. Это предотвращает разделение слов на некотируемых переменных до тех пор, пока IFS не вернется к своему старому значению или пока не будет отменено.

Пример:

$ pattern="/home/me/dir with whitespace/file_*.txt" 

$ ls -l $pattern 
ls: cannot access /home/me/dir: No such file or directory 
ls: cannot access with: No such file or directory 
ls: cannot access whitespace/file_*.txt: No such file or directory 

$ IFS="" 
$ ls -l $pattern 
-rw-r--r-- 1 me  Domain Users 0 Jun 26 09:14 /home/me/dir with whitespace/file_a.txt 
-rw-r--r-- 1 me  Domain Users 0 Jun 26 09:14 /home/me/dir with whitespace/file_b.txt 

$ unset IFS 
$ ls -l $pattern 
ls: cannot access /home/me/dir: No such file or directory 
ls: cannot access with: No such file or directory 
ls: cannot access whitespace/file_*.txt: No such file or directory 

Я узнал, трудный путь, что вы не можете установить и использовать IFS с ls. Например, это не работает:

$ IFS="" ls -l $pattern 

Это потому, что команда уже прошла слово расщепление до тогоIFS изменений.

3

Не держите Glob внутри цитаты, чтобы иметь возможность расширить его:

pattern="/home/me/dir with whitespace/file_" 

ls -l "${pattern}"* 

EDIT:

на основе редактируемого вопроса и комментарии вы можете использовать find:

find . -path "./$pattern" -print0 | xargs -0 ls -l 
+0

Я бы, но в реальном скрипте он передается как параметр, а не жестко закодирован. Например, сценарий вызывается с' ./script.sh'/home/me/dir с whitespace/file_ * .txt ", и внутри скрипта это' pattern = "$ {1}" '. Пробелы и подстановочные знаки могут появляться в любом месте параметра, и я не знаю заранее, где они будут. –

+0

ok check updated ans используя 'find'. Завтра утром вернусь, потому что здесь поздно. – anubhava

Смежные вопросы