Вы можете просто сделать:
case $1 in (/*) pathchk -- "$1";; (*) ! : ;; esac
Этого должно быть достаточно. И он запишет диагностику в stderr и вернет ошибку для недоступных или несоздаваемых компонентов. pathchk
не о существующих путевых именах - это о используемых путевых именах.
Утилита
pathchk
должна проверять, что один или несколько путей действительны (то есть, они могут использоваться для доступа или создания файла, не вызывая синтаксических ошибок) и переносимая ] (то есть без результата усечения имени файла) . Опция-p
предоставляет более обширные проверки переносимости.По умолчанию утилита
pathchk
проверяет каждый компонент каждого операндаpathname
на основе базовой файловой системы. Диагностика должна быть написана для каждого операндаpathname
, который:
длиннее, чем
{PATH_MAX}
байтов (см. Значения переменных Pathname в) Содержит любой компонент, длина которого превышает
{NAME_MAX}
байтов в его содержащем каталогеСодержит любой компонент в каталоге, который недоступен для поиска
Содержит любой символ в любом компоненте, который недействителен в содержащем его каталоге
Формат диагностического сообщения не указан, но должен указывать обнаруженную ошибку и соответствующий операнд
пути
.Не считается ошибкой, если один или несколько компонентов операнда
путевого имени
не существуют, пока может быть создан файл, соответствующийпутевому имени
, указанному отсутствующими компонентами. это не нарушает ни одну из проверок, указанных выше.
Если вы хотите вставить после n
-го символа (где n
- произвольное значение), тогда вы следует избегать sed
. Для этой работы есть инструменты получше (например awk
или perl
, python
и т. Д.), Например. с awk
вы можете использовать переменную n
, чтобы вставить STRING
после n
-го символа в каждое поле, которое соответствует PATTERN
:
awk -vn=2 'BEGIN{FS=OFS=","}{for (i=1; i<=NF; i++){ if ($i ~ /PATTERN/){
h=substr($i,1,n);t=substr($i,n+1,length($i));$i=h "STRING" t}}};1' infile
Предполагается, что ваш файл является простым файлом csv (без запятых в ваших полях).
Другой подход:
$ sed 's/"\([^"]*blah[^"]*"\)/"N\1/g' test.txt
"N1blah8","na","N8blah4"
"N2blah5","na","N10blah4"
"N5blah5","na","1blah234
Регулярное выражение ищет "
, затем 0 или более символов, отличных от "
, за которыми следует бла
, а затем затем 0 или более не- "
снова. Из-за скобок это захвачено и позже может называться \ 1
. Таким образом, команда будет замените совпавший шаблон на себя ( \ 1
), но с добавлением "N
. Вот почему первый "
находится вне скобок. Модификатор / g
в конце заставляет его заменять всю совпадающую строку в каждой строке.
Если ваш sed
] поддерживает его, вы можете упростить его до:
sed -E 's/"([^"]*blah[^"]*")/"N\1/g'
Разбор и обработка CSV может быть действительно сложной задачей. Вот perl oneliner, который ставит N перед первой и третьей колонкой, независимо от содержимого:
Шаг 1, убрать двойные кавычки:
@F = map { /"(.*)"/ } @F;
Шаг 2, вставить N
в первую и третью колонку
$F[0,2] =~ s/^/N/;
Шаг 3, присоединить массив как CSV
printf qq("%s"\n), join q(","), @F
запустить perl:
perl -F, -ane '@F = map { /"(.*)"/ } @F; $F[0,2] =~ s/^/N/; printf qq("%s"\n), join q(","), @F' csvfile
Edit: новый подход, чтобы избежать риска безопасности выражения eval (спасибо terdon).
Чтобы заставить sed
повторять подстановку для всех совпадений в строке, добавьте флаг g
после последнего /
:
$ sed 's/[^"]*blah/N&/g' test.txt
Флаг g
заставит подстановку производиться "для всех непересекающихся совпадений регулярного выражения, а не только для первого" (цитата из руководства на моей системе).
Я также немного изменил регулярное выражение, чтобы совпадали все символы, которые не являются "
перед blah
. Таким образом, подстановка вставит N
непосредственно перед первой цифрой, сразу после "
.